模拟一个 非静态内部类耗时操作
public class InnerClassActivity extends AppCompatActivity {
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_inner_class);
/**
* 内部类对象 对 外部类对象 有一个 隐式的!!!强引用!!!
* 强引用 User u = new User(); 显式的强引用,强可及对象,GC不回收
* 软引用、弱引用、虚引用
*
* 下面的 Thread 匿名内部类实例 引用着一个 InnerClassActivity 实例
*
* 对于一个线程,只有当它的任务(run())完全执行完了,
* 系统才会把这个线程销毁回收,回收之后,
* 这里的 Thread 匿名内部类实例 才不会 引用外部类实例
*
* 但是如果 Thread 的 run() 没有执行完,Activity 即使退出了,
* Thread还在执行,还引用着 Activity,会导致 Activity 无法被回收
* Activity 在 Android中,占用内存是比较大的!
*/
new Thread(new Runnable() {
@Override
public void run() {
//模拟耗时操作
SystemClock.sleep(100000);
}
}).start();
}
}
LeakCanary实战
参考文章
- https://github.com/square/leakcanary 【官网】
- https://square.github.io/leakcanary/getting_started/【需翻墙】
- 性能优化工具(九)-LeakCanary
- LeakCanary 内存泄漏原理完全解析
- 玩转Leakcanary内存泄露分析
- 项目引入依赖
debugCompile 'com.squareup.leakcanary:leakcanary-android:1.5'
releaseCompile 'com.squareup.leakcanary:leakcanary-android-no-op:1.5'
testCompile 'com.squareup.leakcanary:leakcanary-android-no-op:1.5'
- 在 Application 中:
public class LeakApplication extends Application {
@Override public void onCreate() {
super.onCreate();
......
if (LeakCanary.isInAnalyzerProcess(this)) {//1
// This process is dedicated to LeakCanary for heap analysis.
// You should not init your app in this process.
return;
}
LeakCanary.install(this);
}
}
如果当前的进程是用来给LeakCanary 进行堆分析的则return,
否则会执行LeakCanary的install方法,
如果检测到某个Activity 有内存泄露,
LeakCanary 就会给出提示;
并打出发生泄漏的地方;
使用Profiler
使用Profiler,
选择一段陡增的曲线,
选择恰当的排序方式:
也可以看到InnerClassActivity被各种点名:
本文深入探讨Android应用中内存泄漏的问题,特别是由非静态内部类引起的泄漏。通过示例代码展示了如何一个线程内的非静态内部类可以导致Activity无法被垃圾回收,从而引发内存泄漏。同时介绍了LeakCanary这一内存泄漏检测工具的使用方法,包括如何在项目中引入依赖、在Application中初始化以及解读其检测报告。
485

被折叠的 条评论
为什么被折叠?



