我对内存泄漏以及可能导致它们的原因有基本的了解。这就是为什么我不明白自己的代码有问题还是误报的原因。我不知道我应该共享代码的哪一部分,因为该项目并不小。但是请在评论中让我知道,然后我将添加所需的代码。
我使用导航拱形组件并遵循MVVM模式。我后来在项目开发中添加了LeakCanary库,当我在屏幕之间导航时,它立即开始向我发出有关保留实例的警告。
当我向后堆栈中添加片段时,会出现问题。随着向后堆栈中添加的每个片段,保留实例的计数器增加。当阈值达到5时,LeakCanary将转储堆并提供报告。
但是,如果我单击“后退”按钮并返回到先前的屏幕,则保留实例的计数器会减少,最终,当返回到第一个屏幕时,所有保留的实例都会消失。
如果我查看堆分析报告,它表示变量coordinatorLayout泄漏了xml中对CoordinatorLayout
的引用。如果删除该变量及其所有用法,然后再次运行该应用程序,我会看到相同的问题,但是现在有了另一个变量,该变量引用了xml中的另一个视图。我试图删除LeakCanary报告为泄漏的所有视图及其用法。当它说TextView
只是用于在onViewCreated
中设置文本而未在其他任何地方使用时,正在泄漏我开始怀疑我的代码有问题。
我分析了片段中的生命周期方法调用,并注意到当我导航到先前片段的新屏幕时,直到(包括)onDestroyView
之前的所有方法都被调用,而没有onDestroy
。当我单击后退时,onDestroy
被调用以返回位于后退堆栈顶部且保留实例计数器减少的片段。
我怀疑导航组件在回栈中并且LeakCanary将其视为泄漏时正在保留片段的实例。
答案 0 :(得分:2)
这就是后堆栈上的片段的工作方式(导航仅使用现有的Fragment API):片段的视图被破坏了,但是片段本身并未被破坏-它们一直处于if(showLoading) {
this.displayLoader();
return;
}
else {
render (); //your main view
状态,直到您点击返回按钮并返回片段(此后将再次调用CREATED
,然后您将返回到onCreateView()
)。
根据Fragments: Past, Present, and Future talk,对Fragments的未来更改之一是选择启用选项以销毁后堆栈上的Fragment,而不是具有两个单独的生命周期。目前尚不可用。
您必须在RESUMED
中取消对视图的引用,因为这表明Fragment系统不再使用该视图,并且如果您不打算继续使用该视图,则可以安全地对其进行垃圾回收对视图的引用。