【发布时间】:2017-02-14 18:27:09
【问题描述】:
我正在阅读FragmentRetainInstance sample.
在UiFragment 中有变量RetainedFragment mWorkFragment。那么旋转屏幕后如何从内存中删除UiFragment?据我了解,mWorkFragment 是指在屏幕旋转和其他配置更改中仍然存在的东西。
更新 #1
我旋转屏幕并按下 Initiate GC,然后按下 Dump heap。我看到UiFragment 实例的数量是 1。为什么?我希望看到当前方向的 2:1 和上一个方向的 1。
启动 GC:
堆转储:
【问题讨论】:
-
UiFragment不保留。如果保留,则在重新创建宿主 Activity 时不会重新创建它,这就是Fragment#setRetainInstance(...)的工作原理。所以,在你旋转屏幕并初始化一个 gc 之后,之前的UiFragment实例应该被垃圾收集。 -
如何从内存中删除 UiFragment - GC 将从 GC 根(该 UiFragment 实例不是)开始,然后遍历其引用(依此类推) 查看仍然需要哪些对象。所以 mWorkFragment 引用并不重要,因为没有一个对象长期持有对 UiFragment 实例的引用来保持它的活动。
-
@Luksprog,据我从您的评论中了解到,GC 从根(可能是
Application类)开始遍历对象,然后确定UiFragment无法访问(a 之后没有引用配置更改)。所以可以删除。UiFragment是不可达子树的根,mWorkFragment是UiFragment的孩子。如果根不可访问,则其所有子节点均不可访问。对吗? -
你是对的。如果您想查看内存泄漏,在上面的示例中,在 Activity 的 onCreate() 中放置一个断点,然后更改 RetainedFragment 以删除 onDetach() 中的 mProgressBar = null; 行。调试应用程序,第一次遇到断点时只需继续应用程序(尚未创建任何片段),然后旋转手机。您将在 onCreate() 中再次遇到断点,此时如果您查看保留的片段实例,您会看到 mProgressBar 不为空,并且它会泄漏先前的活动,直到达到 onActivityCreated()。
-
@Luksprog,请结合你的cmets并写一个答案,我会接受它
标签: android android-fragments memory-management screen-rotation