删除片段后内存未释放
Memory not freeing after fragment is removed
我有一个 Fragment
其中有一个 RecyclerView
.
在这个RecyclerView
中,我可能会偶尔下载和显示图像(用Glide加载到ImageView
。
因此,当我打开 Fragment
时,已用内存有时可能会从 30MB 左右跳到 100MB 左右甚至更多。
占用Fragment
的Activity
完成后,内存没有释放。和以前一样。
我检查了 Glide 文档,显然我们不必担心在 RecyclerView
中释放 Bitmaps
。这是一个很大的问题,因为应用程序经常因此而因 OOM 而崩溃。
删除 Fragment
后,我应该如何正确处理释放内存?
编辑:另一个观察结果
我注意到的另一件事是,如果我完成 Activity
然后再次开始相同的 Activity
。内存会跳回一会儿,然后回升到 100MB,这让我相信在再次启动 Fragment
之前内存已被清除。
垃圾收集在 Android 中有时是一个痛苦的问题。
大多数开发人员没有考虑这个问题,只是在没有任何资源分配意识的情况下继续开发。
这当然会导致内存泄漏、OOM和不必要的资源绑定等内存问题。 绝对没有自动释放内存的方法。在任何情况下,您都不能仅依赖垃圾收集器
每当您传递片段或 Activity 的 onDestroy() 方法 时,您可以而且应该做的是擦除任何 应该在应用程序中不再需要。您可以执行以下操作:
- 避免听众的匿名实例。创建侦听器并在您不再需要它们时销毁它们。
- 将所有监听器(点击、长按等)设置为空
- 清除所有变量、数组。对 Activity/Fragment
中包含的所有 classes 和子 classes 应用相同的过程
- 每当您对给定的变量执行前面的任何步骤时,将变量设置为 null class(适用于所有变量)
我最后做的是创建一个像
这样的界面
public interface clearMemory(){
void clearMemory();
}
并在每个 class 上实现它,无论是 Activity、片段还是普通 class(包括适配器、自定义视图等)。
然后我会在 class 被销毁时调用该方法(因为应用程序正在被销毁或每当我觉得需要这样做时。注意不要在正常运行时处理)
@Override
public void onDestroy(){
clearMemory();
}
public void clearMemory(){
normalButtonOnClickListener = null;
normalButton.setOnClickListener(null);
normalButton = null;
myCustomClass.clearMemory(); // apply the interface to the class and clear it inside
myCustomClass = null;
simpleVariable = null;
...
}
通过系统地实现这一点,我的应用程序的内存管理变得更加简单和精简。然后就可以 know/control 确切地知道内存是如何以及何时被处理的。
这是对 Ricardo 回答的补充。
您可以在Android中添加以下代码来启动垃圾回收:
Runtime.getRuntime().gc();
注意:在将所有局部变量设为空后调用此函数。执行此代码并不能保证系统会在您的应用程序上进行垃圾收集,它只是暗示现在可能是执行此操作的好时机。
我在我所有的活动中都使用了它onDestroy()
,它似乎总是在我需要的时候起作用。
试试吧,说不定能帮到你。
我有一个 Fragment
其中有一个 RecyclerView
.
在这个RecyclerView
中,我可能会偶尔下载和显示图像(用Glide加载到ImageView
。
因此,当我打开 Fragment
时,已用内存有时可能会从 30MB 左右跳到 100MB 左右甚至更多。
占用Fragment
的Activity
完成后,内存没有释放。和以前一样。
我检查了 Glide 文档,显然我们不必担心在 RecyclerView
中释放 Bitmaps
。这是一个很大的问题,因为应用程序经常因此而因 OOM 而崩溃。
删除 Fragment
后,我应该如何正确处理释放内存?
编辑:另一个观察结果
我注意到的另一件事是,如果我完成 Activity
然后再次开始相同的 Activity
。内存会跳回一会儿,然后回升到 100MB,这让我相信在再次启动 Fragment
之前内存已被清除。
垃圾收集在 Android 中有时是一个痛苦的问题。 大多数开发人员没有考虑这个问题,只是在没有任何资源分配意识的情况下继续开发。
这当然会导致内存泄漏、OOM和不必要的资源绑定等内存问题。 绝对没有自动释放内存的方法。在任何情况下,您都不能仅依赖垃圾收集器
每当您传递片段或 Activity 的 onDestroy() 方法 时,您可以而且应该做的是擦除任何 应该在应用程序中不再需要。您可以执行以下操作:
- 避免听众的匿名实例。创建侦听器并在您不再需要它们时销毁它们。
- 将所有监听器(点击、长按等)设置为空
- 清除所有变量、数组。对 Activity/Fragment 中包含的所有 classes 和子 classes 应用相同的过程
- 每当您对给定的变量执行前面的任何步骤时,将变量设置为 null class(适用于所有变量)
我最后做的是创建一个像
这样的界面public interface clearMemory(){
void clearMemory();
}
并在每个 class 上实现它,无论是 Activity、片段还是普通 class(包括适配器、自定义视图等)。
然后我会在 class 被销毁时调用该方法(因为应用程序正在被销毁或每当我觉得需要这样做时。注意不要在正常运行时处理)
@Override
public void onDestroy(){
clearMemory();
}
public void clearMemory(){
normalButtonOnClickListener = null;
normalButton.setOnClickListener(null);
normalButton = null;
myCustomClass.clearMemory(); // apply the interface to the class and clear it inside
myCustomClass = null;
simpleVariable = null;
...
}
通过系统地实现这一点,我的应用程序的内存管理变得更加简单和精简。然后就可以 know/control 确切地知道内存是如何以及何时被处理的。
这是对 Ricardo 回答的补充。
您可以在Android中添加以下代码来启动垃圾回收:
Runtime.getRuntime().gc();
注意:在将所有局部变量设为空后调用此函数。执行此代码并不能保证系统会在您的应用程序上进行垃圾收集,它只是暗示现在可能是执行此操作的好时机。
我在我所有的活动中都使用了它onDestroy()
,它似乎总是在我需要的时候起作用。
试试吧,说不定能帮到你。