http://www.maiziedu.com/article/9126/
Android中分析内存泄漏的工具MAT
MAT(Memory Analyzer Tools)是一个 Eclipse 插件,它是一个快速、功能丰富的JAVA heap分析工具,它可以帮助我们查找内存泄漏和减少内存消耗。
常见的内存泄漏案例
case 1.单例造成的内存泄漏,单例的静态特性导致其生命周期同应用一样长。
解决方案:
1.将该属性的引用方式改为弱引用
2.如果传入context,使用ApplicationContext
case 2.InnerClass匿名内部类
在Java中,非静态内部类 和 匿名类 都会潜在的引用它们所属的外部类,但是,静态内部类却不会。如果这个非静态内部类实例做了一些耗时的操作,就会造成外围对象不会被回收,从而导致内存泄漏。
解决方案:
1.将内部类变成静态内部类
2.如果有强引用Activity中的属性,则将该属性的引用方式改为弱引用
case 3. Activity Context 的不正确使用
在Android应用程序中通常可以使用两种Context对象:Activity和Application。当类或方法需要Context对象的时候常见的做法是使用第一个作为Context参数。这样就意味着View对象对整个Activity保持引用,因此也就保持对Activty的所有的引用。
假设一个场景,当应用程序有个比较大的Bitmap类型的图片,每次旋转是都重新加载图片所用的时间较多。为了提高屏幕旋转是Activity的创建速度,最简单的方法时将这个Bitmap对象使用Static修饰。 当一个Drawable绑定在View上,实际上这个View对象就会成为这份Drawable的一个Callback成员变量。而静态变量的生命周期要长于Activity。导致了当旋转屏幕时,Activity无法被回收,而造成内存泄露。
解决方案:
1.使用ApplicationContext代替ActivityContext,因为ApplicationContext会随着应用程序的存在而存在,而不依赖activity的生命周期
2.对context的引用不要超过它本身的生命周期
case 4. Handler引起的内存泄漏
当Handler中有延迟的的任务或是等待执行的任务队列过长,由于消息持有对Handler的引用,而Handler又持有对其外部类的潜在引用,这条引用关系会一直保持到消息得到处理,而导致了Activity无法被垃圾回收器回收,而导致了内存泄露。
解决方案:
1.可以把Handler类放在单独的类文件中,或者使用静态内部类便可以避免泄露;
2.如果想在Handler内部去调用所在的Activity,那么可以在handler内部使用弱引用的方式去指向所在Activity.使用Static + WeakReference的方式来达到断开Handler与Activity之间存在引用关系的目的。
case5. 未及时关闭比较耗资源的对象。比如database conn,serivce。