Android App 内存泄露之Thread
Thread 内存泄露
线程也是造成内存泄露的一个重要的源头。线程产生内存泄露的主要原因在于线程生命周期的不可控。
1.看一下以下是否存在问题
<span style="white-space:pre"> </span>/**
*
* @version 1.0.0
* @author Abay Zhuang <br/>
* Create at 2014-7-17
*/
public class ThreadActivity extends Activity {
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
new MyThread().start();
} private class MyThread extends Thread {
@Override
public void run() {
super.run();
dosomthing();
}
}
private void dosomthing(){ }
}
这段代码非常寻常也非常easy,是我们常常使用的形式。
真的没有问题吗
我们思考一个问题:如果MyThread的run函数是一个非常费时的操作,当我们开启该线程后,将设备的横屏变为了竖屏。
普通情况下当屏幕转换时会又一次创建Activity,依照我们的想法。老的Activity应该会被销毁才对,然而其实并不是如此。
因为我们的线程是Activity的内部类。所以MyThread中保存了Activity的一个引用,当MyThread的run函数没有结束时,
MyThread是不会被销毁的。因此它所引用的老的Activity也不会被销毁。因此就出现了内存泄露的问题。
2.这样的线程导致的内存泄露问题应该怎样解决呢?
- 第一、将线程的内部类,改为静态内部类。
第二、在线程内部採用弱引用保存Context引用。 代码例如以下:
<span style="white-space:pre"> </span>/**
*
* @version 1.0.0
* @author Abay Zhuang <br/>
* Create at 2014-7-17
*/ public class ThreadAvoidActivity extends Activity {
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
new MyThread(this).start();
} private void dosomthing() { } private static class MyThread extends Thread {
WeakReference<ThreadAvoidActivity> mThreadActivityRef; public MyThread(ThreadAvoidActivity activity) {
mThreadActivityRef = new WeakReference<ThreadAvoidActivity>(
activity);
} @Override
public void run() {
super.run();
if (mThreadActivityRef == null)
return;
if (mThreadActivityRef.get() != null)
mThreadActivityRef.get().dosomthing();
// dosomthing
}
}
}
上面的两个步骤事实上是切换两个对象的双向强引用链接
- 静态内部类:切断Activity 对于 MyThread的强引用。
- 弱引用: 切断MyThread对于Activity 的强引用。
3.AsynTask 内部类会怎样呢?
有些人喜欢用Android提供的AsyncTask。但其实AsyncTask的问题更加严重,
Thread仅仅有在run函数不结束时才出现这样的内存泄露问题,然而AsyncTask内部的实现机制是运用了ThreadPoolExcutor,
该类产生的Thread对象的生命周期是不确定的。是应用程序无法控制的。
因此假设AsyncTask作为Activity的内部类,就更easy出现内存泄露的问题。
代码例如以下:
/**
*
* 弱引用
* @version 1.0.0
* @author Abay Zhuang <br/>
* Create at 2014-7-17
*/
public abstract class WeakAsyncTask<Params, Progress, Result, WeakTarget>
extends AsyncTask<Params, Progress, Result> {
protected WeakReference<WeakTarget> mTarget; public WeakAsyncTask(WeakTarget target) {
mTarget = new WeakReference<WeakTarget>(target);
} @Override
protected final void onPreExecute() {
final WeakTarget target = mTarget.get();
if (target != null) {
this.onPreExecute(target);
}
} @Override
protected final Result doInBackground(Params... params) {
final WeakTarget target = mTarget.get();
if (target != null) {
return this.doInBackground(target, params);
} else {
return null;
}
} @Override
protected final void onPostExecute(Result result) {
final WeakTarget target = mTarget.get();
if (target != null) {
this.onPostExecute(target, result);
}
} protected void onPreExecute(WeakTarget target) {
// Nodefaultaction
} protected abstract Result doInBackground(WeakTarget target,
Params... params); protected void onPostExecute(WeakTarget target, Result result) {
// Nodefaultaction
}
}
Android App 内存泄露之Thread的更多相关文章
- Android App 内存泄露之调试工具(1)
Android App 内存泄露之工具(1) 使用内存监測工具 DDMS –> Heap 操作步骤 启动eclipse后,切换到DDMS透视图,并确认Devices视图.Heap视图都是打开的, ...
- Android App 内存泄漏Handler
Android App 内存泄露之Handler Handler也是造成内存泄露的一个重要的源头,主要Handler属于TLS(Thread Local Storage)变量,生命周期和Activit ...
- Android 的内存泄露和内存限制
转载自 https://blog.csdn.net/goodlixueyong/article/details/40716779 https://blog.csdn.net/vshuang/artic ...
- Android 常见内存泄露 & 解决方案
前言 内存泄漏(Memory Leak)是指程序中己动态分配的堆内存由于某种原因程序未释放或无法释放,造成系统内存的浪费,导致程序运行速度减慢甚至系统崩溃 (OOM) 等严重后果. 那什么情况下不能被 ...
- Android 防内存泄露handler
Android 防内存泄露handler 1.使用弱引用 WeakRefHander /** * 作者: allen on 15/11/24.感谢开源作者https://coding.net/u/co ...
- Android常见内存泄露,学会这六招优化APP性能
很多开发者都知道,在面试的时候会经常被问到内存泄露和内存溢出的问题. 1.内存溢出(Out Of Memory,简称 OOM),通俗理解就是内存不够,即内存占用超出内存的空间大小. 2.内存泄漏(Me ...
- Android之内存泄露、内存溢出、内存抖动分析
内存 JAVA是在JVM所虚拟出的内存环境中运行的,内存分为三个区:堆.栈和方法区.栈(stack):是简单的数据结构,程序运行时系统自动分配,使用完毕后自动释放.优点:速度快.堆(heap) ...
- Android中内存泄露与如何有效避免OOM总结
一.关于OOM与内存泄露的概念 我们在Android开发过程中经常会遇到OOM的错误,这是因为我们在APP中没有考虑dalvik虚拟机内存消耗的问题. 1.什么是OOM OOM:即OutOfMemoe ...
- 关于Android 的内存泄露及分析
一. Android的内存机制Android的程序由Java语言编写,所以Android的内存管理与Java的内存管理相似.程序员通过new为对象分配内存,所有对象在java堆内分配空间:然而对象的释 ...
随机推荐
- c.vim的安装和使用
之前写了一些废话,今天写的稍微具体点. 在mac上给vim装个插件,,倒腾了半天 先要去找到c.vim.zip,自己百度下,官网就有的,我mac下下来,是直接解压的格式,而不是*.zip,也就是说不需 ...
- 修改Visual Studio2010的主题颜色
第一步:打开工具->扩展管理器 第二步:搜素visual studio color theme editor 第三步:找到Visual Studio Color Theme Editor 第四步 ...
- 用opcity模拟zindex渐变的效果
github地址: https://github.com/echoorx/opacity-Gradient zindex好像不能渐变改变,所以用opcity来模拟 <!DOCTYPE html& ...
- 织梦忘记密码DedeCMS密码重设工具radminpass找回密码
本工具是用于新人忘记管理员密码重设所制作,只需要将radminpass.php文件拷贝到根目录,运行“http://yousite/radminpass.php(yousite为网站域名)”,按照操作 ...
- java网络编程之socket(1)
网络编程是什么 网络编程的本质是两个设备之间的数据交换,当然,在计算机网络中,设备主要指计算机.数据传递本身没有多大的难度,不就是把一个设备中的数据发送给两外一个设备,然后接受另外一个设备反馈的数据. ...
- j2ee学习笔记
Servlet: ①字符集问题:②身份验证:③统一的输入输出:类似母版,重写ServletResponeceWraper的getWriter,使用缓存流. 然后输出时,分析stringWriter , ...
- NagiosQL安装
NagiosQL和Nconf是比较好用的Nagios配置工具. 一.安装NagiosQL 1.在服务器终端运行以下命令: ##YUM安装PHP模块yum -y install --disabl ...
- 模拟试题A
模拟试题A 一.单项选择题(2′*12=24′) 1.下面各种坐标变换中,会产生变换前后维度的改变的是( ) A)建模变换 B)观察变换 C)投影变换 D)视口变换 2.下列描述深度缓冲消隐算法的特点 ...
- FastFDS常用命令
1.启停fastdfs相关服务 #start fastdfs 启动服务 /usr/bin/fdfs_trackerd /etc/fdfs/tracker.conf restart /usr/loca ...
- Centos7 单节点安装 FastDFS + FastDHT服务
Centos7 单节点安装 FastDFS + FastDHT服务 1.安装gcc(编译时需要) FastDFS是C语言开发,安装FastDFS需要先将官网下载的源码进行编译,编译依赖gcc环境,如果 ...