Android 手动释放对象

Gap*_*ton 3 memory android allocation

我已阅读 Android 的性能设计开发人员指南。

我只是想知道,如果我有一个大对象,我无法避免创建它(这很昂贵),当我知道我已经完成它时,我想立即释放它似乎是合乎逻辑的。

似乎没有办法做到这一点。

有人建议将其设置为null,这样系统就会立即GC,这真的是“立即”吗?因为如果系统(Dalvik VM)可以选择不释放我刚刚设置为 null 的大对象,那么将其设置为 null 根本不是解决方案。

将其设置为 null 会鼓励并加快 GC 的说法是否正确?

这种方法是优化应用程序性能的“足够好”的方法吗?或者是否值得付出额外的努力(如果可能的话),在适用的情况下强制 GC 以从任何 Android 设备中挤出最佳性能?

mom*_*omo 5

我认为您不必担心执行 GC 时的详细细节,因为我们无法控制何时调用 gc。即使调用 gc() 也不能保证收集。根据System.gc()的文档

向虚拟机表明现在是运行垃圾收集器的好时机。请注意,这只是一个提示。无法保证垃圾收集器实际上会运行。

在开发具有大对象分配的应用程序时,我会担心以下问题:

  1. 在分配大对象并随后退出该对象的生命周期范围后,我是否会在以后的活动中看到它被 GC 回收?通过使用 adb shell 运行 dumpsys meminfo 可以轻松检查这一点。您基本上在释放后检查内存是否被正确垃圾收集,通常表示随后出现大峰值和下降
  2. 检查这个大对象是否有清晰的GC路径。您可以通过转储 hprof 来检查该对象的引用路径并在内存分析器中检查它来完成此操作。如果是这样,您就安全了,因为 GC 会足够聪明地进行收集。
  3. 分配这个大对象后,堆中是否有足够的填充来执行后续活动?如果对象太大,GC 可能不够快来收集它(这实际上与您的观点有关),并且后续活动的内存消耗加上先前活动的剩余内存实际上可能会导致内存错误。设置 null 并提供清晰的 GC 路径将有助于确保该对象将被适当地进行 GC。我承认这是一个问题,但我的观点是,如果这成为一个问题,我们可能不得不重新考虑这个特定部分的设计方式,看看是否可以对其进行任何优化。
  4. 根据需要通过 onDestroy 对 Activity 进行清理,并确保该 Activity 不被其他人引用,以便它可以得到正确的垃圾收集。例如:我们经常传递活动上下文,却忘记了它会保存其引用。像在位图上调用 recycle() 这样的事情也应该有所帮助。记住这些要点应该有助于在发生第 3 种情况时准备更多空间