【问题标题】:Memory leak in the empty Activity空活动中的内存泄漏
【发布时间】:2016-07-20 00:04:53
【问题描述】:

我最近决定在我的项目中使用leakcanary,所以我创建了一个带有空Activity 的项目仅用于测试,当我运行应用程序时(在没有逻辑代码或视图的项目创建之后)我得到了内存来自该库的泄漏日志:

07-20 04:32:36.742 2967-4915/com.example.leaktest D/LeakCanary: * com.example.leaktest.MainActivity has leaked:
07-20 04:32:36.742 2967-4915/com.example.leaktest D/LeakCanary: * GC ROOT static android.app.ActivityThread.sCurrentActivityThread
07-20 04:32:36.742 2967-4915/com.example.leaktest D/LeakCanary: * references android.app.ActivityThread.mActivities
07-20 04:32:36.742 2967-4915/com.example.leaktest D/LeakCanary: * references android.util.ArrayMap.mArray
07-20 04:32:36.742 2967-4915/com.example.leaktest D/LeakCanary: * references array java.lang.Object[].[1]
07-20 04:32:36.742 2967-4915/com.example.leaktest D/LeakCanary: * references android.app.ActivityThread$ActivityClientRecord.activity
07-20 04:32:36.742 2967-4915/com.example.leaktest D/LeakCanary: * leaks com.example.leaktest.MainActivity instance
07-20 04:32:36.742 2967-4915/com.example.leaktest D/LeakCanary: * Retaining: 1.7KB.
07-20 04:32:36.742 2967-4915/com.example.leaktest D/LeakCanary: * Reference Key: 9180226a-8a65-4c94-9d12-4562a6d88157
07-20 04:32:36.742 2967-4915/com.example.leaktest D/LeakCanary: * Device: Genymotion generic genymotion_vbox86tp_5.1_150409_105318 vbox86tp
07-20 04:32:36.742 2967-4915/com.example.leaktest D/LeakCanary: * Android Version: 5.1 API: 22 LeakCanary: 1.4-beta2 3799172
07-20 04:32:36.742 2967-4915/com.example.leaktest D/LeakCanary: * Durations: watch=5808ms, gc=158ms, heap dump=1953ms, analysis=15795ms

应用程序类:

public class App extends Application {
    @Override
    public void onCreate() {
        super.onCreate();
        refWatcher = LeakCanary.install(this);
    }

    public static RefWatcher getRefWatcher(Context context) {
        App application = (App) context.getApplicationContext();
        return application.refWatcher;
    }

    private RefWatcher refWatcher;
}

MainActivity 类:

public class MainActivity extends AppCompatActivity {

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        App.getRefWatcher(this).watch(this);
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
    }
}

我不知道为什么会这样,如果有人向我解释一下,我将不胜感激。

【问题讨论】:

  • 没有任何代码很难说这里发生了什么......你确定你没有添加任何代码来正确设置泄漏金丝雀吗?
  • 嗨@sockeqwe,正如我提到的,没有代码,只是一个空白活动,在布局文件中没有视图。
  • 没有碎片或其他东西?您是按照文档中的说明在Application.onCreate() 中设置leacanary,还是在您的MainActivity 中做某事?
  • @sockeqwe 什么都没有!我发布了我的代码。
  • 似乎android.app.ActivityThread.sCurrentActivityThread 保持对MainActivity 的静态引用(如果我没记错的话)

标签: android memory-leaks leakcanary


【解决方案1】:

您的RefWatcher 应该在onDestroy() 方法中,而不是onCreate()(参见类似的reported issue here)。

您甚至不需要这样做,因为 LeakCanary 会自动监视 Activity 引用。来自FAQ

LeakCanary.install() 返回一个预配置的 RefWatcher。它还安装了一个 ActivityRefWatcher,它会在调用 Activity.onDestroy() 后自动检测活动是否泄漏。

【讨论】:

  • 我应该收到通知我没有泄漏的日志吗?
  • 说实话,不确定。
  • 你对Refwatcher范围的看法是对的,我没有收到任何泄漏日志
  • 不确定,但我认为图书馆现在应该给出“无泄漏”日志,让我创建一个泄漏并测试您的答案,顺便谢谢
  • 好吧,我进行了测试,没有泄漏,然后没有日志,显然发生内存泄漏时会显示日志,也正如你所说LeakCanary.install 就足够了,谢谢兄弟+1。
猜你喜欢
  • 2012-05-25
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多