线程也是造成内存泄露的一个重要的源头。线程产生内存泄露的主要原因在于线程生命周期的不可控。
1.看一下下面是否存在问题

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(){ }
}

这段代码很平常也很简单,是我们经常使用的形式。

真的没有问题吗?
我们思考一个问题:假设MyThread的run函数是一个很费时的操作,当我们开启该线程后,将设备的横屏变为了竖屏,
一般情况下当屏幕转换时会重新创建Activity,按照我们的想法,老的Activity应该会被销毁才对,然而事实上并非如此。
由于我们的线程是Activity的内部类,所以MyThread中保存了Activity的一个引用,当MyThread的run函数没有结束时,
MyThread是不会被销毁的,因此它所引用的老的Activity也不会被销毁,因此就出现了内存泄露的问题。

2.这种线程导致的内存泄露问题应该如何解决呢?
• 第一、将线程的内部类,改为静态内部类。
• 第二、在线程内部采用弱引用保存Context引用。 代码如下:

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 mThreadActivityRef; public MyThread(ThreadAvoidActivity activity) {
mThreadActivityRef = new WeakReference(
activity);
} @Override
public void run() {
super.run();
if (mThreadActivityRef == null)
return;
if (mThreadActivityRef.get() != null)
mThreadActivityRef.get().dosomthing();
// dosomthing
}
}
}

上面的两个步骤其实是切换两个对象的双向强引用链接
1. 静态内部类:切断Activity 对于 MyThread的强引用。
2. 弱引用: 切断MyThread对于Activity 的强引用。

3.AsynTask 内部类会如何呢?
我们思考一个问题:假设MyThread的run函数是一个很费时的操作,当我们开启该线程后,将设备的横屏变为了竖屏,
一般情况下当屏幕转换时会重新创建Activity,按照我们的想法,老的Activity应该会被销毁才对,然而事实上并非如此。
由于我们的线程是Activity的内部类,所以MyThread中保存了Activity的一个引用,当MyThread的run函数没有结束时,
MyThread是不会被销毁的,因此它所引用的老的Activity也不会被销毁,因此就出现了内存泄露的问题。代码如下:

public abstract class WeakAsyncTask<Params, Progress, Result, WeakTarget>
extends AsyncTask<Params, Progress, Result> {
protected WeakReference mTarget; public WeakAsyncTask(WeakTarget target) {
mTarget = new WeakReference(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 Memory Leak的更多相关文章

  1. Android 内存优化 (防Memory Leak)

      在之前的 Android 内存管理 &Memory Leak & OOM 分析 中,说到了Android的内存管理相关的原理,也能了解到Android Memory Leak 和 ...

  2. Android 内存管理 &Memory Leak & OOM 分析

    转载博客:http://blog.csdn.net/vshuang/article/details/39647167 1.Android 进程管理&内存 Android主要应用在嵌入式设备当中 ...

  3. Android Memory/Resource Leak总结

    Android的内存/资源泄露,不容易发现,又会引发app甚至是system的一系列问题. 在这里我根据以往碰到的相关问题,总结出了一些检测和修改方法. *有可能造成memory leak的代码是Fr ...

  4. 安卓android WebView Memory Leak WebView内存泄漏

    Android WebView Memory Leak WebView内存泄漏 在这次开发过程中,需要用到webview展示一些界面,但是加载的页面如果有很多图片就会发现内存占用暴涨,并且在退出该界面 ...

  5. Android 内存管理 &amp;Memory Leak &amp; OOM 分析

    1.Android 流程管理&内存 Android主要应用在嵌入式设备其中.而嵌入式设备因为一些众所周知的条件限制,通常都不会有非常高的配置,特别是内存是比較有限的. 假设我们编写的代 码其中 ...

  6. Android 常见 Memory Leak 原因及解决办法总结

    待整理: http://geek.csdn.net/news/detail/50692 背景 在Android开发过程中,我们经常碰到的情况就是在我们不清楚为什么情况下,程序突然出现Crash了.其中 ...

  7. 内存泄漏(Memory Leak)

    什么情况下会导致内存泄露(Memory Leak)? Android 的虚拟机是基于寄存器的Dalvik,它的最大堆大小一般是16M,有的机器为24M.因此我们所能利用 的内存空间是有限的.如果我们的 ...

  8. quartz集群报错but has failed to stop it. This is very likely to create a memory leak.

    quartz集群报错but has failed to stop it. This is very likely to create a memory leak. 在一台配置1核2G内存的阿里云服务器 ...

  9. 山东省第七届ACM省赛------Memory Leak

    Memory Leak Time Limit: 2000MS Memory limit: 131072K 题目描述 Memory Leak is a well-known kind of bug in ...

随机推荐

  1. iOS平台基于ffmpeg的视频直播技术揭秘

    现在非常流行直播,相信很多人都跟我一样十分好奇这个技术是如何实现的,正好最近在做一个ffmpeg的项目,发现这个工具很容易就可以做直播,下面来给大家分享下技术要点: 首先你得编译出ffmpeg运行所需 ...

  2. My.Ioc 代码示例——谈一谈如何实现装饰器模式,兼谈如何扩展 My.Ioc

    装饰器模式体现了一种“组合优于继承”的思想.当我们要动态为对象增加新功能时,装饰器模式往往是我们的好帮手. 很多后期出现的 Ioc 容器都为装饰器模式提供了支持,比如说 Autofac.在 My.Io ...

  3. #BeginLibraryItem 的疑问...

    <!-- #BeginLibraryItem "/library/ur_here.lbi" --><div style="padding:3px 15p ...

  4. Java方法的参数是按值传递的.【转】

    在Java中,所有的方法参数,都是"按值传递". 有那么一种说法,Java中基本类型是按值传递,对象是按引用传递.这个说法其实是不确切的,确切的说法是 Java中基本类型将值作为参 ...

  5. strace 使用

  6. UICollectionView出现the behavior of the UICollectionViewFlowLayout is not defined because:

    2015-01-28 21:55:17.790 Demo[636:9351] the behavior of the UICollectionViewFlowLayout is notdefined ...

  7. 重拾C++ 基础知识总结(二)

    1.标准库string类型: 用户程序要使用string类型对象,必须包含相关头文件 #include <string> 字符串字面值与标准库string类型不是同一种类型,字符串字面值是 ...

  8. jsp中button传值

    onclick=location.href("linker.jsp?custno="+ from1.custno.value)或者onClick ="a()" ...

  9. interrupt & storage & DMA

    1.Interrupt: The occurrence of an event is usually signaled by aninterrupt from either the hardware ...

  10. Win7下启用IIS7

    1.进入“控制面板-->程序”: 2.点击“打开或关闭Windows功能” 3.选择“Internet信息服务”相关选项,如下: 点击“确定”后,请稍等.. 5.启用成功后,可在浏览器访问:ht ...