我正在努力更好地寻找 Android 中的内存泄漏。
我将举几个例子,但首先,由于您提出的问题与您的主题无关,我将首先解释您在“实例视图”中看到的内容;
是这个$0吗?
this$0
是编译器生成的合成变量,表示“超出我的范围”,它是非静态内部类的父对象。
我应该如何判断哪些值得调查?
这取决于,如果depth
是 0 并且它是你的代码 - 调查,也许这是一个长期运行的任务,结束条件不好。
在 Memory Profiler 中分析堆转储时,您可以过滤 Android Studio 认为可能表明应用中的 Activity 和 Fragment 实例存在内存泄漏的分析数据。
过滤器显示的数据类型包括:
在某些情况下,例如以下情况,过滤器可能会产生误报:
过滤堆转储以查找内存泄漏。
分析记忆的技巧
在使用 Memory Profiler 时,您应该强调您的应用程序代码并尝试强制内存泄漏。
在您的应用程序中引发内存泄漏的一种方法是在检查堆之前让它运行一段时间。
泄漏可能会蔓延到堆中分配的顶部。
但是,泄漏越小,您需要运行应用程序才能看到它的时间越长。
您还可以通过以下方式之一触发内存泄漏:
- 在不同的活动状态下,将设备从纵向旋转到横向并再次旋转多次。旋转设备通常会导致应用程序泄漏 Activity、Context 或 View 对象,因为系统会重新创建 Activity,并且如果您的应用程序在其他地方持有对这些对象之一的引用,则系统无法对其进行垃圾收集。
- 在不同的活动状态下在您的应用程序和另一个应用程序之间切换(导航到主屏幕,然后返回到您的应用程序)。
不断增长的图表是一个重要指标
如果您观察到一条仅持续上升而很少下降的趋势线,则可能是由于内存泄漏,这意味着无法释放某些内存。或者根本没有足够的内存来处理应用程序。当应用程序达到其内存限制并且 Android 操作系统无法为应用程序分配更多内存时,将抛出 OutOfMemoryError。
短时间内出现震荡
湍流是不稳定的指标,这也适用于 Android 内存使用情况。当我们观察到这种模式时,通常会在其短暂的生命周期中创建并丢弃大量昂贵的对象。
CPU 在执行垃圾收集时浪费了很多周期,而没有为应用程序执行实际工作。用户可能会遇到缓慢的 UI,在这种情况下我们绝对应该优化我们的内存使用。
如果我们谈论 Java 内存泄漏
public class ThreadActivity extends Activity {
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_async_task);
new DownloadTask().start();
}
private class DownloadTask extends Thread {
@Override
public void run() {
SystemClock.sleep(2000 * 10);
}
}
}
内部类包含对其封闭类的隐式引用,它将自动生成一个构造函数并将活动作为对它的引用传递。
上面的代码其实是
public class ThreadActivity extends Activity {
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_async_task);
new DownloadTask(this).start();
}
private class DownloadTask extends Thread {
Activity activity;
public DownloadTask(Activity activity) {
this.activity = activity;
}
@Override
public void run() {
SystemClock.sleep(2000 * 10);
}
}
}
在正常情况下,用户打开活动等待 20 秒,直到下载任务完成。
任务完成后,堆栈释放所有对象。
然后下次垃圾收集器工作时,他将从堆中释放对象。
当用户关闭活动时,主方法将从堆栈中释放,线程活动也从堆中回收,一切都按需要工作而不会泄漏。
在用户在 10 秒后关闭/旋转活动的情况下。
任务仍在工作,这意味着活动的引用仍然存在,我们有内存泄漏
注意:当下载 run() 任务完成时,堆栈释放对象。所以当垃圾收集器下一次工作时,对象将从堆中回收,因为它上面没有引用对象。
相关的 Youtube 播放列表
而且https://square.github.io/leakcanary/fundamentals/很棒。