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

  1. public class ThreadActivity extends Activity {
  2. public void onCreate(Bundle savedInstanceState) {
  3. super.onCreate(savedInstanceState);
  4. setContentView(R.layout.activity_main);
  5. new MyThread().start();
  6. }
  7.  
  8. private class MyThread extends Thread {
  9. @Override
  10. public void run() {
  11. super.run();
  12. dosomthing();
  13. }
  14. }
  15. private void dosomthing(){
  16.  
  17. }
  18. }

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

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

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

  1. public class ThreadAvoidActivity extends Activity {
  2. public void onCreate(Bundle savedInstanceState) {
  3. super.onCreate(savedInstanceState);
  4. setContentView(R.layout.activity_main);
  5. new MyThread(this).start();
  6. }
  7.  
  8. private void dosomthing() {
  9.  
  10. }
  11.  
  12. private static class MyThread extends Thread {
  13. WeakReference mThreadActivityRef;
  14.  
  15. public MyThread(ThreadAvoidActivity activity) {
  16. mThreadActivityRef = new WeakReference(
  17. activity);
  18. }
  19.  
  20. @Override
  21. public void run() {
  22. super.run();
  23. if (mThreadActivityRef == null)
  24. return;
  25. if (mThreadActivityRef.get() != null)
  26. mThreadActivityRef.get().dosomthing();
  27. // dosomthing
  28. }
  29. }
  30. }

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

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

  1. public abstract class WeakAsyncTask<Params, Progress, Result, WeakTarget>
  2. extends AsyncTask<Params, Progress, Result> {
  3. protected WeakReference mTarget;
  4.  
  5. public WeakAsyncTask(WeakTarget target) {
  6. mTarget = new WeakReference(target);
  7. }
  8.  
  9. @Override
  10. protected final void onPreExecute() {
  11. final WeakTarget target = mTarget.get();
  12. if (target != null) {
  13. this.onPreExecute(target);
  14. }
  15. }
  16.  
  17. @Override
  18. protected final Result doInBackground(Params... params) {
  19. final WeakTarget target = mTarget.get();
  20. if (target != null) {
  21. return this.doInBackground(target, params);
  22. } else {
  23. return null;
  24. }
  25. }
  26.  
  27. @Override
  28. protected final void onPostExecute(Result result) {
  29. final WeakTarget target = mTarget.get();
  30. if (target != null) {
  31. this.onPostExecute(target, result);
  32. }
  33. }
  34.  
  35. protected void onPreExecute(WeakTarget target) {
  36. // Nodefaultaction
  37. }
  38.  
  39. protected abstract Result doInBackground(WeakTarget target,
  40. Params... params);
  41.  
  42. protected void onPostExecute(WeakTarget target, Result result) {
  43. // Nodefaultaction
  44. }
  45. }

 

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. Swift: 下标(Subscripts)

    类.结构体.枚举都可以定义下标(subscript),下标是访问集合.列表.序列的元素的快捷方式. 在Swift中可以为类型定义下标,而且不限于一维. 语法 下标定义的方法:跟实例方法的语法类似,su ...

  2. TCP异常终止(reset报文)

    在之前做智能家居系统时,师弟做的服务端与WiFI盒子(客户端)进行通信时,总是出现异常情况,然后服务端不停地向客户端发送RESET报文,之前一直都不知道是什么情况,因此一直不知道是什么问题导致的,今天 ...

  3. 谈谈iOS中粘性动画以及果冻效果的实现

    在最近做个一个自定义PageControl——KYAnimatedPageControl中,我实现了CALayer的形变动画以及CALayer的弹性动画,效果先过目: https://github.c ...

  4. MVC模式下的数据展示:EasyUI的datagrid

    我的数据库设计是一张老师表teacher,一张学生表student,一个教师对应多个学生,在学生一方建立外键; 还有一点想清楚,需要展示的数据是根据什么来的,是成功登陆的用户的id?还是直接展示所有的 ...

  5. Django初探--开发环境搭建(笔记)

    1. Django框架的安装 (1) 下载Django源码 Django-1.7.11.tar.gz,并解压,网址:https://www.djangoproject.com/download/ (2 ...

  6. uva 1391 Astronauts(2-SAT)

    /*翻译好题意 n个变量 不超过m*2句话*/ #include<iostream> #include<cstdio> #include<cstring> #inc ...

  7. python函数的使用和返回值

    #coding=utf-8 def a(): i=1a() #函数的返回值,用return语句实现 #一个返回值的情况def test(): i=7 return iprint test() #多个返 ...

  8. ASP.NET页面错误处理

    ASP.NET 提供三种用于在出现错误时捕获和响应错误的主要方法:Page_Error 事件.Application_Error 事件以及应用程序配置文件 (Web.config). 这里主要介绍Ap ...

  9. c# 使用递归 循环遍历导航树结构 并解析

    1.数据书库结构 1 家用电器 0 一级菜单 2 手机.数码.京东通信 0 一级菜单 3 电脑.办公 0 一级菜单 4 家具.家居.厨房 0 一级菜单 5 男装.女装.童装.内衣 0 一级菜单 6 个 ...

  10. 四大跨平台的APP分析

    转载:http://blog.csdn.net/kenkao/article/details/50678269