LeakCanary 在 Activity 上使用 Fragments 检测到内存泄漏
Memory Leak detected by LeakCanary on Activity with Fragments
我们在 2.0 版 $ git clone https://source.codeaurora.org/quic/la/camera-samples -b iot-concam-apk.lnx.1.1
中有 2 个明显的内存泄漏(看起来相同),它们会在应用程序关闭时消失。
它们在应用程序启动后立即发生。
一次又一次地切换选项卡不会增加泄漏的数量,我认为这是一件好事。
我用 https://square.github.io/leakcanary/getting_started/ 抓到了它
我注意到如果我们更改所有 'replace' 以在 onCreate 中添加,则 2 次泄漏发生在 Tab 开关上而不是应用程序启动时。
2021-01-28 09:21:41.781 28582-28582/com.android.example.camera2.video D/LeakCanary:
┬───
│ GC Root: System class
│
├─ android.view.inputmethod.InputMethodManager class
│ Leaking: NO (InputMethodManager↓ is not leaking and a class is never leaking)
│ ↓ static InputMethodManager.sInstance
├─ android.view.inputmethod.InputMethodManager instance
│ Leaking: NO (DecorView↓ is not leaking and InputMethodManager is a singleton)
│ ↓ InputMethodManager.mCurRootView
├─ com.android.internal.policy.DecorView instance
│ Leaking: NO (LinearLayout↓ is not leaking and View attached)
│ View is part of a window view hierarchy
│ View.mAttachInfo is not null (view attached)
│ View.mWindowAttachCount = 1
│ mContext instance of com.android.internal.policy.DecorContext, wrapping activity com.example.android.camera2.video.
│ CameraActivity with mDestroyed = false
│ ↓ DecorView.mContentRoot
├─ android.widget.LinearLayout instance
│ Leaking: NO (CameraActivity↓ is not leaking and View attached)
│ View is part of a window view hierarchy
│ View.mAttachInfo is not null (view attached)
│ View.mWindowAttachCount = 1
│ mContext instance of com.example.android.camera2.video.CameraActivity with mDestroyed = false
│ ↓ View.mContext
├─ com.example.android.camera2.video.CameraActivity instance
│ Leaking: NO (FragmentContainerView↓ is not leaking and Activity#mDestroyed is false)
│ mApplication instance of android.app.Application
│ mBase instance of android.app.ContextImpl
│ ↓ CameraActivity.container
├─ androidx.fragment.app.FragmentContainerView instance
│ Leaking: NO (View attached)
│ View is part of a window view hierarchy
│ View.mAttachInfo is not null (view attached)
│ View.mID = R.id.fragment_container
│ View.mWindowAttachCount = 1
│ mContext instance of com.example.android.camera2.video.CameraActivity with mDestroyed = false
│ ↓ View.mKeyedTags
│ ~~~~~~~~~~
├─ android.util.SparseArray instance
│ Leaking: UNKNOWN
│ Retaining 3.1 kB in 117 objects
│ ↓ SparseArray.mValues
│ ~~~~~~~
├─ java.lang.Object[] array
│ Leaking: UNKNOWN
│ Retaining 3.1 kB in 115 objects
│ ↓ Object[].[0]
│ ~~~
├─ androidx.navigation.NavHostController instance
│ Leaking: UNKNOWN
│ Retaining 3.1 kB in 114 objects
│ mActivity instance of com.example.android.camera2.video.CameraActivity with mDestroyed = false
│ mContext instance of com.example.android.camera2.video.CameraActivity with mDestroyed = false
│ ↓ NavController.mLifecycleOwner
│ ~~~~~~~~~~~~~~~
╰→ androidx.navigation.fragment.NavHostFragment instance
Leaking: YES (ObjectWatcher was watching this because androidx.navigation.fragment.NavHostFragment received
Fragment#onDestroy() callback and Fragment#mFragmentManager is null)
Retaining 1.7 kB in 57 objects
key = 1350d8e9-4d31-42de-9bff-693ddce5f5ef
watchDurationMillis = 16748
retainedDurationMillis = 11748
METADATA
Build.VERSION.SDK_INT: 29
Build.MANUFACTURER: QUALCOMM
LeakCanary version: 2.6
App process name: com.android.example.camera2.video
Stats: LruCache[maxSize=3000,hits=2630,misses=44837,hitRate=5%]
RandomAccess[bytes=2279092,reads=44837,travel=13095741867,range=14884449,size=19192832]
Heap dump reason: user request
Analysis duration: 5510 ms
由于泄漏的数量没有增加,并且它们在应用程序关闭时消失,我想我们可以顺其自然,但我仍然无法找到 2 次泄漏的原因。
真的是漏电吗?
任何信息将不胜感激。
我已经修复了内存泄漏问题。
在我的 XML 中不使用 androidx.fragment.app.FragmentContainerView
是解决方案。
相反,我使用了 ConstraintLayout。
如果您不在 XML 中使用 app:navGraph="@navigation/nav_graph"
控制片段,而是在 activity[=13= 中使用 replace<CameraFragmentSnapshot>(R.id.fragment_container, null, null)
,我认为您不应该使用它]
您正在点击 this issue,这是针对 Navigation 2.2.3 或更高版本修复的。请升级到最新稳定版本的Navigation (2.3.3) 来解决这个问题。
我们在 2.0 版 $ git clone https://source.codeaurora.org/quic/la/camera-samples -b iot-concam-apk.lnx.1.1
中有 2 个明显的内存泄漏(看起来相同),它们会在应用程序关闭时消失。
它们在应用程序启动后立即发生。 一次又一次地切换选项卡不会增加泄漏的数量,我认为这是一件好事。
我用 https://square.github.io/leakcanary/getting_started/ 抓到了它 我注意到如果我们更改所有 'replace' 以在 onCreate 中添加,则 2 次泄漏发生在 Tab 开关上而不是应用程序启动时。
2021-01-28 09:21:41.781 28582-28582/com.android.example.camera2.video D/LeakCanary:
┬───
│ GC Root: System class
│
├─ android.view.inputmethod.InputMethodManager class
│ Leaking: NO (InputMethodManager↓ is not leaking and a class is never leaking)
│ ↓ static InputMethodManager.sInstance
├─ android.view.inputmethod.InputMethodManager instance
│ Leaking: NO (DecorView↓ is not leaking and InputMethodManager is a singleton)
│ ↓ InputMethodManager.mCurRootView
├─ com.android.internal.policy.DecorView instance
│ Leaking: NO (LinearLayout↓ is not leaking and View attached)
│ View is part of a window view hierarchy
│ View.mAttachInfo is not null (view attached)
│ View.mWindowAttachCount = 1
│ mContext instance of com.android.internal.policy.DecorContext, wrapping activity com.example.android.camera2.video.
│ CameraActivity with mDestroyed = false
│ ↓ DecorView.mContentRoot
├─ android.widget.LinearLayout instance
│ Leaking: NO (CameraActivity↓ is not leaking and View attached)
│ View is part of a window view hierarchy
│ View.mAttachInfo is not null (view attached)
│ View.mWindowAttachCount = 1
│ mContext instance of com.example.android.camera2.video.CameraActivity with mDestroyed = false
│ ↓ View.mContext
├─ com.example.android.camera2.video.CameraActivity instance
│ Leaking: NO (FragmentContainerView↓ is not leaking and Activity#mDestroyed is false)
│ mApplication instance of android.app.Application
│ mBase instance of android.app.ContextImpl
│ ↓ CameraActivity.container
├─ androidx.fragment.app.FragmentContainerView instance
│ Leaking: NO (View attached)
│ View is part of a window view hierarchy
│ View.mAttachInfo is not null (view attached)
│ View.mID = R.id.fragment_container
│ View.mWindowAttachCount = 1
│ mContext instance of com.example.android.camera2.video.CameraActivity with mDestroyed = false
│ ↓ View.mKeyedTags
│ ~~~~~~~~~~
├─ android.util.SparseArray instance
│ Leaking: UNKNOWN
│ Retaining 3.1 kB in 117 objects
│ ↓ SparseArray.mValues
│ ~~~~~~~
├─ java.lang.Object[] array
│ Leaking: UNKNOWN
│ Retaining 3.1 kB in 115 objects
│ ↓ Object[].[0]
│ ~~~
├─ androidx.navigation.NavHostController instance
│ Leaking: UNKNOWN
│ Retaining 3.1 kB in 114 objects
│ mActivity instance of com.example.android.camera2.video.CameraActivity with mDestroyed = false
│ mContext instance of com.example.android.camera2.video.CameraActivity with mDestroyed = false
│ ↓ NavController.mLifecycleOwner
│ ~~~~~~~~~~~~~~~
╰→ androidx.navigation.fragment.NavHostFragment instance
Leaking: YES (ObjectWatcher was watching this because androidx.navigation.fragment.NavHostFragment received
Fragment#onDestroy() callback and Fragment#mFragmentManager is null)
Retaining 1.7 kB in 57 objects
key = 1350d8e9-4d31-42de-9bff-693ddce5f5ef
watchDurationMillis = 16748
retainedDurationMillis = 11748
METADATA
Build.VERSION.SDK_INT: 29
Build.MANUFACTURER: QUALCOMM
LeakCanary version: 2.6
App process name: com.android.example.camera2.video
Stats: LruCache[maxSize=3000,hits=2630,misses=44837,hitRate=5%]
RandomAccess[bytes=2279092,reads=44837,travel=13095741867,range=14884449,size=19192832]
Heap dump reason: user request
Analysis duration: 5510 ms
由于泄漏的数量没有增加,并且它们在应用程序关闭时消失,我想我们可以顺其自然,但我仍然无法找到 2 次泄漏的原因。 真的是漏电吗? 任何信息将不胜感激。
我已经修复了内存泄漏问题。
在我的 XML 中不使用 androidx.fragment.app.FragmentContainerView
是解决方案。
相反,我使用了 ConstraintLayout。
如果您不在 XML 中使用 app:navGraph="@navigation/nav_graph"
控制片段,而是在 activity[=13= 中使用 replace<CameraFragmentSnapshot>(R.id.fragment_container, null, null)
,我认为您不应该使用它]
您正在点击 this issue,这是针对 Navigation 2.2.3 或更高版本修复的。请升级到最新稳定版本的Navigation (2.3.3) 来解决这个问题。