建立LeakCanaery的检测环境
1. 修改chrome的build.gradle
apply plugin: 'com.android.application'
dependencies {
compile fileTree(dir: 'libs', exclude: 'android-support-multidex.jar', include: '*.jar')
compile 'com.android.support:multidex:1.0.0'
compile project(':mediaplayer')
compile project(':web_contents_delegate_android')
compile project(':browser_I')
compile project(':chromium_gen')
compile files('libs/hugo-annotations-1.2.1-sources.jar')
compile files('libs/decrawso.jar')
compile files('libs/qihoospeechrecognition.jar')
compile files('libs/QHStatAgent.jar')
compile files('libs/adsdk_0.1.16.1125.jar')
compile files('libs/andfix.jar')
compile files('libs/opensdk-release.jar')
//添加下面2行
debugCompile 'com.squareup.leakcanary:leakcanary-android:1.3'
releaseCompile 'com.squareup.leakcanary:leakcanary-android-no-op:1.3'
}
2. 修改ChromeApplication.java
@Override
public void onCreate() {
UmaUtils.recordMainEntryPointTime();
super.onCreate();
LeakCanary.install(this);
3. 手动测试, 当发生memory leak的时候就会在桌面创建出Leaks图标
经过测试, 确实发现浏览器有不少内存泄露的地方.
memory_leak.png4. 解决这些问题的code patch
memory_leak_code_patch.png常见的代码错误汇总
场景1. 进入某个activity, 然后退出, 再进入.
场景2. 频繁退出, 进入浏览器.
1. static 对象持有了具体activity的context
static的对象(生命周期是整个app运行期), 在创建时传入了某个具体的Activity对象, 当这个activity退出时(onDestroy()被调用), 这个activity对象无法被释放.
解决办法: static对象如果要用到context的话, 就要使用applicationContext, 不要使用activity context.
例如:
public class ToastHelper implements BrowserOnDestroyListener {
private static Toast mToast;
public void init(Context context) {
if (mToast == null) {
try {
mToast = new Toast(context);
mToast.setDuration(Toast.LENGTH_SHORT);
mToast.setView(inflate.inflate(R.layout.transient_notification, null));
} catch (Exception e) {
}
}
}
//应该改为:
public void init(Context context) {
if (mToast == null) {
try {
mToast = new Toast(context.getApplicationContext());
mToast.setDuration(Toast.LENGTH_SHORT);
mToast.setView(inflate.inflate(R.layout.transient_notification, null));
} catch (Exception e) {
}
}
}
2. 对单例的Manager, 只调用了addListener(), 忘记在销毁时调用removeListener().
例如:
public class BottomMenuBar extends LinearLayout {
public BottomMenuBar(Context context, AttributeSet attrs) {
super(context, attrs);
mContext = context;
setOrientation(HORIZONTAL);
ThemeModeManager.getInstance().addThemeModeListener(this, true);
}
//需要添加下面的代码
//否则ThemeModeManager的listeners会一直持有BottomMenuBar的对象, 导致BottomMenuBar被销毁后, 它所占的内存无法被回收.
@Override
protected void onDetachedFromWindow() {
super.onDetachedFromWindow();
ThemeModeManager.getInstance().removeThemeModeListener(this);
}
}
refer to:
http://www.liaohuqiu.net/cn/posts/leak-canary-read-me/
======DONE======
网友评论