内存泄露的定义

根据百度百科的定义:内存泄漏也称作“存储渗漏”,用动态存储分配函数动态开辟的空间,在使用完毕后未释放,结果导致一直占据该内存单元。直到程序结束。(其实说白了就是该内存空间使用完毕之后未回收)即所谓内存泄露,在Android里就是 该回收的资源没有被GC(垃圾回收机制)回收,因为界面(Activity)在android中占比很大,所以Activity的内存泄露很常见。又由于Activity中加入了对各种资源的引用,特别是图片资源,所以Activity的回收意义重大。

由于单例中保有Activity对象

当某一个单例中需要使用Context作为参数的时候,我们常常在界面中将Activity.this传入到单例中。

package com.example.memoryleak;import android.content.Context;public class AppManager {private static AppManager appManager;private static Context context;private AppManager(){appManager = new AppManager();}public static AppManager getInstance(Context context){AppManager.context = context;if(appManager==null){appManager = new AppManager();}return appManager;}}
这样代码看似没有问题,但是当你在界面中调用finish()方法以后,你的Activity不能及时的回收。

原因:

AppManager对象是static类型的,这就注定这个对象的生命周期比很多的Activity生命周期都要长很多,在Activity被关闭以后,垃圾回收器视图回收这块内存区域,但是AppManager保有此界面的引用,这样GC就无法完成回收,造成此界面常驻内存,引发内存泄露。

解决办法:

1,针对参数不必是Activity的: 在单例中不要传入Activity,可以用Application.getContext()作为参数。因为Application类的生命周期伴随整个应用的启动和关闭,单例的生命周期和Application大致相同。 2,针对必须传入Activity做参数的: 把activity作为方法内部变量使用,因为当此方法执行完以后,方法内部的变量就会被释放。这样单例就不会保有界面的引用,从而避免内存泄露。

由于使用Handler导致的内存泄露

<span style="font-size:18px;">package com.example.memoryleak;import android.app.Activity;import android.os.Bundle;import android.os.Handler;/** *内存泄露的几种情形 * @author yuanyang * */public class MainActivity extends Activity {private Handler mHandler = new Handler(){public void handleMessage(android.os.Message msg) {};};    @Override    protected void onCreate(Bundle savedInstanceState) {        super.onCreate(savedInstanceState);        setContentView(R.layout.activity_main);    }  }</span>


在使用Handler+Message模型的时候。Eclispe会提示我们

- This Handler class should be static or leaks might occur (com.example.memoryleak.MainActivity.1)。eclipse提示我们:handler要定义成static,不然会出现内存泄露。

原因:

由于handler+message的实现机制,handler.sendMessage(msg)将Message对象送入到消息队列中,消息队列是在应用创建的时候生成,在应用退出的时候销毁。此时消息队列可能很繁忙,造成当前消息不能及时处理,而Handler得handleMessage方法得不到及时运行,这样handler对象的引用始终在消息队列里面,导致Handler不能被回收,而保有该handler得Activity就不能就是得到回收,造成内存泄露。

解决方法:

将Handler定义成static类型的。因为static类型的变量不属于任何特定的类,这样在Activity回收的时候就不会因为Handler而得不到及时回收。 以上是我对安卓内存泄露的拙见,有意见的可以留言

更多相关文章

  1. Android内存管理之道
  2. Android 内存泄漏的检测和解决
  3. 避免android程序开发内存泄漏
  4. 警惕rapidxml的陷阱(二):在Android上默认内存池分配数组过大,容易导
  5. Qt on Android:创建可伸缩界面
  6. 【Android 内存优化】Bitmap 图像尺寸缩小 ( 设置 Options 参数

随机推荐

  1. Apache Flink 商业公司 Ververica 又有几
  2. 一文了解 Apache Hive 联邦查询(Query Fed
  3. 从行存储到 RCFile,Facebook 为什么要设计
  4. K8S进阶实践 之 ConfigMap配置文件挂载
  5. Prism:Uber 的 Presto 查询网关服务
  6. 面试专题—iOS内存不够怎么办?底层原理
  7. crudapi零代码开发平台应用场景和成功案
  8. 3.21 将vCenter Server添加到Active Dire
  9. 函数作用域与闭包-回调函数-函数的多值返
  10. 使用grid布局简单仿PHP中文网首页