首先寫個內存泄漏的例子:單例模式
import android.content.Context;
/**
* @Author: david.lvfujiang
* @Date: 2019/12/5
* @Describe: 單例模式
*/
public class JavaBean {
private static JavaBean bean;
private Context context;
private static JavaBean javaBean;
public JavaBean(Context context) {
this.context = context;
}
public static JavaBean createBean(Context context) {
if (javaBean == null) {
javaBean = new JavaBean(context);
return javaBean;
}
return javaBean;
}
}
public class MainActivity extends AppCompatActivity {
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
Button button = findViewById(R.id.button);
//創建單例對象
JavaBean javaBean = JavaBean.createBean(this);
button.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
Intent intent = new Intent();
intent.setClass(MainActivity.this, Main2Activity.class);
startActivity(intent);
finish();
}
});
}
}
上訴的單例對象持有Activity的引用,然後我們在Activity中創建單例對象,之後我們跳轉到第二個Activity,然後調用finsh方法銷燬Activity。
1.點擊 Profiler > MEMORY
2.進入MEMORY界面後點擊刪除按鈕手動進行GC,再點擊刪除按鈕右邊的按鈕進行內存分析,會出現如下界面
3.選擇搜索的方式是根據包名,然後找到我們的Activity
點擊Activity後右邊會出現一個窗口,點擊該對象就可以看到它在內存中的引用情況
說明我們的Actiivty被JavaBean這個單例類持有引用
我們再給Activity添加一個匿名的線程類看看
public class MainActivity extends AppCompatActivity {
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
Button button = findViewById(R.id.button);
//創建單例對象
JavaBean javaBean = JavaBean.createBean(this);
button.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
Intent intent = new Intent();
intent.setClass(MainActivity.this, Main2Activity.class);
startActivity(intent);
finish();
}
});
new Thread(){
@Override
public void run() {
for(;;){
}
}
}.start();
}
}
添加匿名線程類,子線程執行一個死循環。我們知道內部類會持有外部類的引用,所以肯定會發現內存泄漏。經過上訴步驟找到我們的Activity
XXX in Thread…說明就是我們使用匿名內部類發生了內存泄漏