我对内存泄漏以及导致内存泄漏的原因有基本的了解.这就是为什么我不明白我的代码中是否有问题,或者是误报.我不知道该分享哪部分代码,因为这个项目并不小.但是请在 comments 中告诉我,我会添加所需的代码.

I use navigation arch component and follow MVVM pattern. I added LeakCanary library later in the development of project and it immediately started to give me warnings about retained instances when I navigate between screens.

The problem occurs when I add fragments to the back stack. With each added fragment to the back stack the counter of retained instances increases. When it reaches the threshold value of 5 LeakCanary dumps the heap and provides report.

But if I click on back button and return to previous screens then counter of retained instances decreases and eventually, when returned to 1st screen all retained instances disappear.

If I look at heap analysis reports it says that the variable coordinatorLayout which is a reference to the CoordinatorLayout in xml has leaked. If I remove the variable and all of its usage and run the app again I see the same problem, but now with another variable that is a reference to another view in xml. I tried to remove all of the views and their usage that LeakCanary reported as leaking. When it said that a TextView, which is just used to set a text in onViewCreated and not used anywhere else, is leaking I started to doubt that there is a problem in my code.

我分析了片段中的生命周期方法调用,注意到当我导航到前一个片段的新屏幕时,调用了onDestroyView及之前的所有方法,但不调用onDestroy.当我单击"上一步"时,会为位于后台堆栈顶部的片段调用onDestroy,并且保留的实例计数器会减少.

我怀疑导航组件将片段的实例保留在后台堆栈中,而LeakCanary将其视为泄漏.

推荐答案

这就是后堆栈上的片段的工作方式(导航只是使用现有的片段API):片段的视图被销毁,但片段本身并没有被销毁——它们保持在CREATED状态,直到您点击后退按钮并返回到片段(之后将再次调用onCreateView(),您将返回到RESUMED).

根据Fragments: Past, Present, and Future talk,碎片future 的变化之一是 Select 加入选项,以销毁后堆栈上的碎片,而不是有两个单独的生命周期.目前还没有.

You have to null out your references to the views in onDestroyView as that's the sign that the view is no longer being used by the Fragment system and it can be safely garbage collected if it wasn't for your continued reference to the View.

Kotlin相关问答推荐

插入/更新/upsert时不发出房间流

关键字';在When Kotlin When-语句中

Kotlin中一个接口的实现问题

T和T有什么区别:任何>

将一个列表元素分组为多个组(indexBy)

即使 Kotlin 的 `Map` 不是 `Iterable`,它如何以及为什么是可迭代的?

伴随对象在变量更改时更改它的值

Kotlin 有垃圾收集器吗?如果是这样,它基于哪种算法?

参考 Kotlin 中的 Java 接口静态字段

将 Gradle 子元素与 Kotlin 多平台一起使用

使用最新的 com.jakewharton.rxbinding3:rxbinding:3.0.0-alpha2 库时未找到 RxTextView 和其他小部件

如何使用 Coil 从 URL 获取位图?

变量后的Android问号

如何在 Android Studio 3.1.3 中查看 Kotlin 中有趣的源代码?

Kotlin中的测试无法访问受保护(protected)的方法

Firestore - 如何在 Kotlin 中排除数据类对象的字段

Kotlin替换字符串中的多个单词

Android Kotlin .visibility

使用 Moshi/Retrofit2 访问深度嵌套的 JSON 数组

如何在 IntelliJ IDEA 中禁用粘贴时将 Java 转换为 Kotlin?