LeakCanary 检测到我的 Java Android 应用程序中存在泄漏 - Google 地图

war*_*o09 2 java android memory-leaks leakcanary

我对这个场景比较陌生,几乎没有编程背景,因此如果我问一些愚蠢的问题,我提前道歉。\n我使用 SupportMapFragment 显示谷歌地图。我这样做是为了防止 onDestroyView() 中的泄漏,但是不知道这是对还是错?

\n
@Override\nprotected void onDestroy() {\n    super.onDestroy();\n    mMap.clear();\n    mapView.onDestroy();\n}\n
Run Code Online (Sandbox Code Playgroud)\n

完整代码在这里:

\n

https://github.com/warfo09/warforepo/blob/main/MainActivity.java

\n

这是我退出应用程序时得到的结果:

\n
  \xe2\x94\x82 GC Root: Local variable in native code\n  \xe2\x94\x82\n  \xe2\x94\x9c\xe2\x94\x80 com.google.maps.api.android.lib6.gmm6.vector.n instance\n  \xe2\x94\x82    Leaking: UNKNOWN\n  \xe2\x94\x82    Retaining 1391172 bytes in 9076 objects\n  \xe2\x94\x82    Thread name: \'RenderDrive\'\n  \xe2\x94\x82    \xe2\x86\x93 n.e\n  \xe2\x94\x82        ~\n  \xe2\x94\x9c\xe2\x94\x80 com.google.maps.api.android.lib6.gmm6.vector.p instance\n  \xe2\x94\x82    Leaking: UNKNOWN\n  \xe2\x94\x82    Retaining 1391005 bytes in 9073 objects\n  \xe2\x94\x82    \xe2\x86\x93 p.k\n  \xe2\x94\x82        ~\n  \xe2\x94\x9c\xe2\x94\x80 com.google.maps.api.android.lib6.gmm6.api.ac instance\n  \xe2\x94\x82    Leaking: UNKNOWN\n  \xe2\x94\x82    Retaining 1390953 bytes in 9072 objects\n  \xe2\x94\x82    View not part of a window view hierarchy\n  \xe2\x94\x82    View.mAttachInfo is null (view detached)\n  \xe2\x94\x82    View.mWindowAttachCount = 1\n  \xe2\x94\x82    mContext instance of android.app.Application\n  \xe2\x94\x82    \xe2\x86\x93 ac.mParent\n  \xe2\x94\x82         ~~~~~~~\n  \xe2\x94\x9c\xe2\x94\x80 android.widget.FrameLayout instance\n  \xe2\x94\x82    Leaking: UNKNOWN\n  \xe2\x94\x82    Retaining 405651 bytes in 5497 objects\n  \xe2\x94\x82    View not part of a window view hierarchy\n  \xe2\x94\x82    View.mAttachInfo is null (view detached)\n  \xe2\x94\x82    View.mWindowAttachCount = 1\n  \xe2\x94\x82    mContext instance of android.app.Application\n  \xe2\x94\x82    \xe2\x86\x93 FrameLayout.mParent\n  \xe2\x94\x82                  ~~~~~~~\n  \xe2\x94\x9c\xe2\x94\x80 com.google.android.gms.maps.MapView instance\n  \xe2\x94\x82    Leaking: YES (View.mContext references a destroyed activity)\n  \xe2\x94\x82    Retaining 403455 bytes in 5482 objects\n  \xe2\x94\x82    View not part of a window view hierarchy\n  \xe2\x94\x82    View.mAttachInfo is null (view detached)\n  \xe2\x94\x82    View.mID = R.id.mapsView\n  \xe2\x94\x82    View.mWindowAttachCount = 1\n  \xe2\x94\x82    mContext instance of com.app.trikojis.MainActivity with mDestroyed = true\n  \xe2\x94\x82    \xe2\x86\x93 MapView.mContext\n  \xe2\x95\xb0\xe2\x86\x92 com.app.trikojis.MainActivity instance\n  \xe2\x80\x8b     Leaking: YES (ObjectWatcher was watching this because com.app.trikojis.MainActivity received Activity#onDestroy()\n  \xe2\x80\x8b     callback and Activity#mDestroyed is true)\n  \xe2\x80\x8b     Retaining 60455 bytes in 956 objects\n  \xe2\x80\x8b     key = f3613896-cce8-4aac-a73a-d4a79700c719\n  \xe2\x80\x8b     watchDurationMillis = 56451\n  \xe2\x80\x8b     retainedDurationMillis = 51448\n  \xe2\x80\x8b     mApplication instance of android.app.Application\n  \xe2\x80\x8b     mBase instance of androidx.appcompat.view.ContextThemeWrapper, not wrapping known Android context\n  \n  METADATA\n  \n  Build.VERSION.SDK_INT: 28\n  Build.MANUFACTURER: samsung\n  LeakCanary version: 2.5\n  App process name: com.app.trikojis\n  Stats: LruCache[maxSize=3000,hits=5749,misses=110455,hitRate=4%]\n  RandomAccess[bytes=5714581,reads=110455,travel=48839777691,range=35924253,size=41590935]\n  Analysis duration: 11845 ms```\n\n\n\n   \n
Run Code Online (Sandbox Code Playgroud)\n

Pie*_*cau 9

泄漏跟踪表明 MainActivity 已被销毁,但由 MapView 保存在内存中,MapView 将该 Activity 作为其上下文。

现在,真正奇怪的是,MapView 是一个以 Application 作为上下文的 FrameLayout 的父级,它本身是一个名为“ac”(混淆名称)的视图的父级,该视图由“RenderDrive”的字段保存“线程实例。

这绝对是 Google 地图库中的一个错误。您应该在他们的错误跟踪器上报告该问题,也可以随意使用我刚刚发布的这个答案。

我不知道到底是什么错误导致了此泄漏,但您可以通过在活动被销毁时删除 MapView 的所有子级来修复它。

@Override
protected void onDestroy() {
    super.onDestroy();
    mMap.clear();
    mapView.onDestroy();
    mapView.removeAllViews();
}
Run Code Online (Sandbox Code Playgroud)

  • 多年来所有这些无用/错误的答案,而真正的答案就坐在这里,只有 2 票?真丢脸!谷歌为什么这么多年不修复它! (4认同)