android – Fragment中的内存泄漏

我正在使用LeakCanary库来监控我的应用程序中的内存泄漏。我收到这个内存泄漏,不知道如何跟踪造成的内容。

05-09 09:32:14.731  28497-31220/? D/LeakCanary﹕ In com.etiennelawlor.minesweeper:0.0.21:21.
    * com.etiennelawlor.minesweeper.fragments.MinesweeperFragment has leaked:
    * GC ROOT com.google.android.gms.games.internal.GamesClientImpl$PopupLocationInfoBinderCallbacks.zzahO
    * references com.google.android.gms.games.internal.PopupManager$PopupManagerHCMR1.zzajo
    * references com.google.android.gms.games.internal.GamesClientImpl.mContext
    * references com.etiennelawlor.minesweeper.activities.MinesweeperActivity.mFragments
    * references android.app.FragmentManagerImpl.mAdded
    * references java.util.ArrayList.array
    * references array java.lang.Object[].[0]
    * leaks com.etiennelawlor.minesweeper.fragments.MinesweeperFragment instance
    * Reference Key: 2f367393-6dfd-4797-8d85-7ac52c431d07
    * Device: LGE google Nexus 5 hammerhead
    * Android Version: 5.1 API: 22
    * Durations: watch=5015ms, gc=141ms, heap dump=1978ms, analysis=23484ms

这是我的回购:https://github.com/lawloretienne/Minesweeper

这似乎是一个难以捉摸的。我设置了一个界面来在片段和活动之间进行通信。我将这个mCoordinator Interface变量设置在onAttach()中,然后我意识到我没有在onDetach()中将其置零。我修复了这个问题,但仍然有内存泄漏。有任何想法吗?

更新

我禁用了片段泄漏监视,并且我仍然收到有关泄漏事件的通知,并附带以下泄漏痕迹:

05-09 17:07:33.074  12934-14824/? D/LeakCanary﹕ In com.etiennelawlor.minesweeper:0.0.21:21.
    * com.etiennelawlor.minesweeper.activities.MinesweeperActivity has leaked:
    * GC ROOT com.google.android.gms.games.internal.GamesClientImpl$PopupLocationInfoBinderCallbacks.zzahO
    * references com.google.android.gms.games.internal.PopupManager$PopupManagerHCMR1.zzajo
    * references com.google.android.gms.games.internal.GamesClientImpl.mContext
    * leaks com.etiennelawlor.minesweeper.activities.MinesweeperActivity instance
    * Reference Key: f4d06830-0e16-43a2-9750-7e2cb77ae24d
    * Device: LGE google Nexus 5 hammerhead
    * Android Version: 5.1 API: 22
    * Durations: watch=5016ms, gc=164ms, heap dump=3430ms, analysis=39535ms
documentation表示即使状态为“连接”或“连接”,也可以安全地连接()。它也表示你可以安全地调用disconnect(),无论连接状态是什么。因此,我将删除对connect()和disconnect()的调用中的“if”语句。但是,我怀疑这将使这个“泄漏”消失。

很明显,GamesClientImpl正在将您的Activity作为上下文存储引用。我想象这是在建立您的GoogleApiClient.Builder.build()时发生的GoogleApiClient。对于我来说,似乎是一个错误,GoogleApiClient的实例仍然在您的活动完成后。但是,如果你应该调用onStart()和onStop()中的connect(),这似乎意味着你可以重用连接(因为onStart()和onStop()可以重复调用)。为了使其工作,即使调用了disconnect(),GoogleApiClient也必须保持对Context的引用。

当创建GoogleApiClient时,您可以尝试使用全局应用程序上下文而不是您的Activity上下文,因为全局应用程序上下文将永远存在(直到进程被杀死)。这应该使你的“泄漏”消失:

// Create the Google Api Client with access to Plus and Games
mGoogleApiClient = new GoogleApiClient.Builder(getApplicationContext())
    .addConnectionCallbacks(this)
    .addOnConnectionFailedListener(this)
    .addApi(Plus.API).addScope(Plus.SCOPE_PLUS_LOGIN)
    .addApi(Games.API).addScope(Games.SCOPE_GAMES)
    .build();
http://stackoverflow.com/questions/30144432/memory-leak-in-fragment

本站文章除注明转载外,均为本站原创或编译
转载请明显位置注明出处:android – Fragment中的内存泄漏