使用LeakCannary 检测内存泄漏
引入依赖库
最新版本的leakcanary不需要插入任何代码,仅仅需要添加build.gradle中加入以下依赖即可:
dependencies {
debugImplementation 'com.squareup.leakcanary:leakcanary-android:2.0'
}
单例模式引起的内存泄漏
单例对象持有上下文Context的引发的内存泄漏,因为单例对象的生命周期比较长,相当于应用程序Application的生命周期,如果Context使用的是当前Activity或者Fragment中的上下文,则生命周期较短,因此,当生命周期较长的对象引用了“较短”的上下文,会出现这样的情况,当Context所属的Activity或者Fragment 生命周期结束时(可能执行了onDestroy),Java的垃圾回收机制尝试回收该Activity时发现该类还存在引用(单例对象持有了这个引用),则会引发内存泄漏。所以当单例中用到Context时,Context不要再使用Activity或Fragment等,使用context.getApplicationContext()(即生命周期较长的上下文)即可。
this.context = context.getApplicationContext();
ActivityManager 单例添加Activity实例对象引发的内存泄漏
这个情况是我项目中的,比较特殊,因为我所负责的模块是以module依赖的形式存在于主项目中,因此不能使用Application这个类(大家应该知道原因吧),但是我还需要写一个对Activity进行管理的类,就有了ActivityManager这个单例类.
造成内存泄漏的原因和第一种Context的情况基本是一致的,但是处理方式不同,毕竟这个单例存储的是一个Activity的实例,泄漏原因可想而知,当Activity生命周期结束时,作为单例的ActivityManager还持有Activity的这个实例,因此引发了内存泄漏,这个时候,我好像没有办法使用全局的Context了,这个时候,我只能想到了谷歌推荐使用的弱引用WeakReference,也比较简单,修改好的单例写法如下:
package com.chaoxing.email.utils;
import android.app.Activity;
import android.content.Context;
import java.lang.ref.WeakReference;
import java.util.HashMap;
/**
* Created by sdj on 2017/4/13.
*/
public class ActivityManager {
private HashMap<String, WeakReference<Activity>> activities = new HashMap<>();
private static ActivityManager activityManager;
private ActivityManager() {
}
public static ActivityManager getInstance() {
if (null == activityManager) {
activityManager = new ActivityManager();
}
return activityManager;
}
public void addActivity(Activity activity) {
if (null != activity) {
activities.put(activity.getClass().getSimpleName(), new WeakReference<>(activity));
}
}
public void exitApp() {
for (String key : activities.keySet()) {
WeakReference<Activity> weakReference = activities.get(key);
if (null != weakReference && weakReference.get() != null) {
weakReference.get().finish();
}
}
}
public static boolean isContextInvalid(final Context context) {
return context == null || ((Activity) context).isFinishing();
}
}
修改后运行了程序,关闭Activity,等待了10秒(LeakCannary的检测机制),没有发现泄漏,反复几次,并没有发现内存泄漏。
————————————————
版权声明:本文为CSDN博主「布丁西西」的原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接及本声明。
原文链接:https://blog.csdn.net/shenshibaoma/article/details/77980836
网友评论