#android #memory-leaks #leakcanary
Вопрос:
Я пытаюсь устранить эти утечки. Но я понятия не имею, в чем проблема.
1.
┬───
│ GC Root: System class
│
├─ android.os.Looper class
│ Leaking: NO (Thread↓ is not leaking and a class is never leaking)
│ ↓ static Looper.sMainLooper
├─ android.os.Looper instance
│ Leaking: NO (Thread↓ is not leaking)
│ ↓ Looper.mThread
├─ java.lang.Thread instance
│ Leaking: NO (the main thread always runs)
│ Thread name: 'main'
│ ↓ Thread.threadLocals
│ ~~~~~~~~~~~~
├─ java.lang.ThreadLocal$ThreadLocalMap instance
│ Leaking: UNKNOWN
│ Retaining 2.2 kB in 69 objects
│ ↓ ThreadLocal$ThreadLocalMap.table
│ ~~~~~
├─ java.lang.ThreadLocal$ThreadLocalMap$Entry[] array
│ Leaking: UNKNOWN
│ Retaining 2.1 kB in 68 objects
│ ↓ ThreadLocal$ThreadLocalMap$Entry[].[21]
│ ~~~~
├─ java.lang.ThreadLocal$ThreadLocalMap$Entry instance
│ Leaking: UNKNOWN
│ Retaining 28 B in 1 objects
│ ↓ ThreadLocal$ThreadLocalMap$Entry.value
│ ~~~~~
├─ android.animation.AnimationHandler instance
│ Leaking: UNKNOWN
│ Retaining 29.7 MB in 54029 objects
│ ↓ AnimationHandler.mAnimationCallbacks
│ ~~~~~~~~~~~~~~~~~~~
├─ java.util.ArrayList instance
│ Leaking: UNKNOWN
│ Retaining 29.7 MB in 54025 objects
│ ↓ ArrayList.elementData
│ ~~~~~~~~~~~
├─ java.lang.Object[] array
│ Leaking: UNKNOWN
│ Retaining 29.7 MB in 54024 objects
│ ↓ Object[].[0]
│ ~~~
├─ android.animation.ValueAnimator instance
│ Leaking: UNKNOWN
│ Retaining 875 B in 28 objects
│ ↓ Animator.mListeners
│ ~~~~~~~~~~
├─ java.util.ArrayList instance
│ Leaking: UNKNOWN
│ Retaining 60 B in 2 objects
│ ↓ ArrayList.elementData
│ ~~~~~~~~~~~
├─ java.lang.Object[] array
│ Leaking: UNKNOWN
│ Retaining 40 B in 1 objects
│ ↓ Object[].[0]
│ ~~~
├─ android.view.ViewPropertyAnimator$AnimatorEventListener instance
│ Leaking: UNKNOWN
│ Retaining 368 B in 12 objects
│ ↓ ViewPropertyAnimator$AnimatorEventListener.this$0
│ ~~~~~~
├─ android.view.ViewPropertyAnimator instance
│ Leaking: UNKNOWN
│ Retaining 356 B in 11 objects
│ ↓ ViewPropertyAnimator.mView
│ ~~~~~
├─ androidx.appcompat.widget.AppCompatImageView instance
│ Leaking: YES (View.mContext references a destroyed activity)
│ Retaining 1.2 kB in 19 objects
│ View is part of a window view hierarchy
│ View.mAttachInfo is null (view detached)
│ View.mID = R.id.iv_energy
│ View.mWindowAttachCount = 1
│ mContext instance of com.example.components.ui.result.
│ ResultVer2Activity with mDestroyed = true
│ ↓ View.mContext
╰→ com.example.components.ui.result.ResultVer2Activity instance
Leaking: YES (ObjectWatcher was watching this because com.example.components.ui.result.ResultVer2Activity received
Activity#onDestroy() callback and Activity#mDestroyed is true)
Retaining 18.4 MB in 13058 objects
key = dc4c55d5-5d97-4091-b7ad-0cd2a49f4d09
watchDurationMillis = 6804
retainedDurationMillis = 1799
mApplication instance of com.example.MyApplication
mBase instance of androidx.appcompat.view.ContextThemeWrapper
METADATA
Build.VERSION.SDK_INT: 30
Build.MANUFACTURER: Google
LeakCanary version: 2.6
App process name: com.example
Count of retained yet cleared: 12 KeyedWeakReference instances
Stats: LruCache[maxSize=3000,hits=8027,misses=155358,hitRate=4%]
RandomAccess[bytes=7640055,reads=155358,travel=107845991097,range=28570681,size=
41968225]
Heap dump reason: 7 retained objects, app is visible
Analysis duration: 87264 ms
│ GC Root: Global variable in native code
│
├─ android.widget.Toast$TN instance
│ Leaking: UNKNOWN
│ Retaining 524.3 kB in 16111 objects
│ ↓ Toast$TN.mPresenter
│ ~~~~~~~~~~
├─ android.widget.ToastPresenter instance
│ Leaking: UNKNOWN
│ Retaining 522.4 kB in 16104 objects
│ mContext instance of com.example.components.ui.exam.
│ ExamEntryActivity with mDestroyed = true
│ ↓ ToastPresenter.mContext
│ ~~~~~~~~
╰→ com.example.components.ui.exam.ExamEntryActivity instance
Leaking: YES (ObjectWatcher was watching this because com.example.components.ui.exam.ExamEntryActivity received
Activity#onDestroy() callback and Activity#mDestroyed is true)
Retaining 354.3 kB in 12305 objects
key = dce008b9-d99a-4dfa-be4f-a5b0ae8917cb
watchDurationMillis = 57521
retainedDurationMillis = 52002
mApplication instance of com.example.MyApplication
mBase instance of androidx.appcompat.view.ContextThemeWrapper
METADATA
Build.VERSION.SDK_INT: 30
Build.MANUFACTURER: Google
LeakCanary version: 2.6
App process name: com.example
Count of retained yet cleared: 2 KeyedWeakReference instances
Stats: LruCache[maxSize=3000,hits=10382,misses=177073,hitRate=5%]
RandomAccess[bytes=10509449,reads=177073,travel=81077330786,range=32700295,size=
48659081]
Heap dump reason: 6 retained objects, app is visible
Analysis duration: 16424 ms
Как я могу прочитать эту трассировку и устранить проблему?
Ответ №1:
Первая утечка происходит из-за того, что что-то настраивает аниматор на R. id.iv_energy ImageView. Аниматор должен быть отменен, когда этот вид отсоединен, но это не так, аниматор все еще работает и удерживает изображение.
Второе происходит потому, что тост произносит местный судья. Отмена тоста может помочь или создать тост с контекстом приложения вместо контекста действия.