安卓新手,内存泄漏问题

2021-07-26 15:03:59 +08:00
 alalalizy

问题描述

报错情况

D/HomePageFragment: BaseFragment-->onPause()
D/DiscoveryFragment: BaseFragment-->onPause()
D/TvItemsFragment: BaseFragment-->onPause()
D/MainActivity: BaseActivity-->onPause()
D/LeakCanary: Scheduling check for retained objects in 5000ms because app became invisible
D/HomePageFragment: BaseFragment-->onStop()
D/DiscoveryFragment: BaseFragment-->onStop()
D/CommendFragment: BaseFragment-->onStop()
D/TvItemsFragment: BaseFragment-->onStop()
D/MainActivity: BaseActivity-->onStop()
D/MainActivity: BaseActivity-->onSaveInstanceState()

D/LeakCanary: ====================================
    HEAP ANALYSIS RESULT
    ====================================
    1 APPLICATION LEAKS
    
    References underlined with "~~~" are likely causes.
    Learn more at https://squ.re/leaks.
    
    53078 bytes retained by leaking objects
    Signature: b01ba777d9ce636d68e71237f54fafe95ee827f8
    ┬───
    │ 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 (ViewRootImpl↓ is not leaking and InputMethodManager is a singleton)
    │    ↓ InputMethodManager.mCurRootView
    ├─ android.view.ViewRootImpl instance
    │    Leaking: NO (ViewPager2$RecyclerViewImpl↓ is not leaking and ViewRootImpl#mView is not null)
    │    ↓ ViewRootImpl.mImeFocusController
    ├─ android.view.ImeFocusController instance
    │    Leaking: NO (ViewPager2$RecyclerViewImpl↓ is not leaking)
    │    ↓ ImeFocusController.mNextServedView
    ├─ androidx.viewpager2.widget.ViewPager2$RecyclerViewImpl instance
    │    Leaking: NO (SearchFragment↓ is not leaking and View attached)
    │    mContext instance of com.moviemore.android.ui.MainActivity with mDestroyed = false
    │    View.parent androidx.viewpager2.widget.ViewPager2 attached as well
    │    View#mParent is set
    │    View#mAttachInfo is not null (view attached)
    │    View.mID = R.id.null
    │    View.mWindowAttachCount = 1
    │    ↓ ViewPager2$RecyclerViewImpl.mAdapter
    ├─ com.moviemore.android.ui.common.ui.BaseViewPagerFragment$VpAdapter instance
    │    Leaking: NO (SearchFragment↓ is not leaking)
    │    ↓ BaseViewPagerFragment$VpAdapter.mFragmentManager
    ├─ androidx.fragment.app.FragmentManagerImpl instance
    │    Leaking: NO (SearchFragment↓ is not leaking)
    │    ↓ FragmentManagerImpl.mFragmentStore
    ├─ androidx.fragment.app.FragmentStore instance
    │    Leaking: NO (SearchFragment↓ is not leaking)
    │    ↓ FragmentStore.mActive
    ├─ java.util.HashMap instance
    │    Leaking: NO (SearchFragment↓ is not leaking)
    │    ↓ HashMap.table
    ├─ java.util.HashMap$Node[] array
    │    Leaking: NO (SearchFragment↓ is not leaking)
    │    ↓ HashMap$Node[].[6]
    ├─ java.util.HashMap$Node instance
    │    Leaking: NO (SearchFragment↓ is not leaking)
    │    ↓ HashMap$Node.value
    ├─ androidx.fragment.app.FragmentStateManager instance
    │    Leaking: NO (SearchFragment↓ is not leaking)
    │    ↓ FragmentStateManager.mFragment
    ├─ com.moviemore.android.ui.search.SearchFragment instance
    │    Leaking: NO (Fragment#mFragmentManager is not null)
    │    ↓ SearchFragment.rootView
    │                     ~~~~~~~~
    ╰→ android.widget.LinearLayout instance
    ​     Leaking: YES (ObjectWatcher was watching this because com.moviemore.android.ui.search.SearchFragment received Fragment#onDestroyView() callback (references to its views should be cleared to prevent leaks))
    ​     key = 888671cb-ecda-4776-b4dd-b4f2350acb32
    ​     watchDurationMillis = 7210
    ​     retainedDurationMillis = 2208
    ​     mContext instance of com.moviemore.android.ui.MainActivity with mDestroyed = false
    ​     View#mParent is null
    ​     View#mAttachInfo is null (view detached)
    ​     View.mWindowAttachCount = 1
    ====================================
    0 LIBRARY LEAKS
9117 次点击
所在节点    Android
3 条回复
JellyBeanX
2021-07-27 09:48:42 +08:00
要么,在 A 的 onDestroyView() 中销毁 LinearLayout 的实例,要么把 replace 换成 show & hide
JellyBeanX
2021-07-27 10:43:08 +08:00
@JellyBeanX 说错了,是销毁持有 linearLayout 实例的对象
ukyoo
2021-07-29 16:08:15 +08:00
onDestroyView()后要手动把成员变量的 View 置空, 因为下一次 onCreateView()还会重新 infalte 一次布局, 这个成员变量就没什么用了, 视为泄露. https://www.jianshu.com/p/15ad41477f34

这是一个专为移动设备优化的页面(即为了让你能够在 Google 搜索结果里秒开这个页面),如果你希望参与 V2EX 社区的讨论,你可以继续到 V2EX 上打开本讨论主题的完整版本。

https://www.v2ex.com/t/791832

V2EX 是创意工作者们的社区,是一个分享自己正在做的有趣事物、交流想法,可以遇见新朋友甚至新机会的地方。

V2EX is a community of developers, designers and creative people.

© 2021 V2EX