Android LocationManager泄漏内存

时间:2020-06-24 08:44:16

标签: android leakcanary

我通过活动的getSystemSercice(LOCATION_SERVICE)获得了LocationManager实例,几分钟后,泄漏金丝雀检测到内存泄漏:

┬───
│ GC Root: Global variable in native code
│
├─ android.location.LocationManager$ListenerTransport instance
│    Leaking: UNKNOWN
│    ↓ LocationManager$ListenerTransport.this$0
│                                        ~~~~~~
├─ android.location.LocationManager instance
│    Leaking: UNKNOWN
│    ↓ LocationManager.mContext
│                      ~~~~~~~~
├─ android.app.ContextImpl instance
│    Leaking: UNKNOWN
│    ↓ ContextImpl.mAutofillClient
│                  ~~~~~~~~~~~~~~~
╰→ com....manager.MapsActivity instance
​     Leaking: YES (ObjectWatcher was watching this because com...manager.live2.MapsActivity received Activity#onDestroy() callback and Activity#mDestroyed is true)
​     key = 3e8186a7-b057-4c0a-aca2-b0fc4257bb11
​     watchDurationMillis = 107841
​     retainedDurationMillis = 102829

METADATA

Build.VERSION.SDK_INT: 29
Build.MANUFACTURER: Xiaomi
LeakCanary version: 2.3
App process name: com...
Analysis duration: 9763 ms```

1 个答案:

答案 0 :(得分:1)

我先前的答案是错误的,因为我假设ContextImpl与以基础上下文为基础的活动具有不同的生命周期。事实证明它们具有相同的生命周期(在此处评论:https://issuetracker.google.com/issues/159308651#comment6

对于此特定问题,意味着泄漏在其他地方。仔细阅读源代码和泄漏跟踪:

  • LocationManager有一个mContext字段,该字段指向引用活动的ContextImpl。这意味着LocationManager的生命周期应该与活动之一相同。
  • 但是,它由LocationManager$ListenerTransport保存在内存中,getSystemSercice(LOCATION_SERVICE)是本机内存保存的绑定器,用于允许另一个进程回调到该进程。直到其他过程放开对活页夹的引用,该活页夹才能在应用程序端进行GC。这是一个经典的AOSP泄漏,并且该修补程序应该是在活动为毁了。

这一切都在AOSP中。在您的应用程序中,您可以尝试在应用程序上下文而不是活动上下文上调用this.getSystemSercice(LOCATION_SERVICE);吗?即在您的活动中而不是this.getApplication().getSystemSercice(LOCATION_SERVICE);尝试locationManager.removeUpdates(this);

编辑:或者可能是活动代码未调用yarn start --port=9090

相关问题