MemoryLeakAnalysis-非静态内部类的静态实例造成内存泄漏

非静态内部类的静态实例容易造成内存泄漏

代码示例

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
package info.enjoycode.memoryleak;

import android.os.Bundle;
import android.support.v7.app.AppCompatActivity;

public class MainActivity extends AppCompatActivity {
private static final String TAG = "MainActivity";
static Demo sInstance;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
if(sInstance ==null){
sInstance = new Demo();
}
}

class Demo{
}
}

模拟泄露&原因分析

上面的代码中的sInstance实例类型为静态实例,在第一个MainActivity act1实例创建时,sInstance会获得并一直持有act1的引用。当MainAcitivity销毁后重建,因为sInstance持有act1的引用,所以act1是无法被GC回收的,进程中会存在2个MainActivity实例(act1和重建后的MainActivity实例),这个act1对象就是一个无用的但一直占用内存的对象,即无法回收的垃圾对象。所以,对于lauchMode不是singleInstance的Activity, 应该避免在activity里面实例化其非静态内部类的静态实例。

多次晃动手机后,通过Android Studio的Monitor监测

  • 导出hprof,从下图我们可以看到MainActivity现在有7个实例

  • 查找真凶,sIntance引用了MainActivity。解决方案网上已经有很多,这里就不记录了。

ref

Android 开发进阶之『清除应用中的内存泄漏』

高效地分析Android内存–MAT工具解析

文章目录
  1. 1. 非静态内部类的静态实例容易造成内存泄漏
    1. 1.1. 代码示例
    2. 1.2. 模拟泄露&原因分析
    3. 1.3. ref