安卓内存监视器 - "触发GC"

3
我使用安卓工具“内存监测器”来修补内存泄漏,它非常有用。然而,我需要澄清一点。有时候,在运行应用程序后,已分配的内存为“47MB”。当应用程序与用户交互时,它会上下波动。然后,当我点击“引起GC”时,已分配的内存降至“30MB”。如果我再次点击,它会降到“17MB”。我的应用程序从17MB开始。我为什么需要点击两次“引起GC”才能回收所有内存?这是意外情况吗?还是我只需点击一次?
1个回答

2
观察每个周期前后堆上的对象集合可能会告诉你更多关于发生了什么事情。这可能是由于GC策略决策(例如,分代收集器不扫描所有代)或者是由于对象彼此引用方式造成的。
其中一个可能的情况与finalization和本地指针有关。假设位图对象具有本机组件,并且该本机组件具有JNI全局引用到另一个对象(可能是一个带有像素数据的byte[])。第一次GC将释放位图。在GC完成后不久,位图的finalizer将运行,释放JNI全局ref。然而,byte[]仍然在堆上,直到下一个GC通过注意到它不再被引用为止。(这就是Skia库实际处理Bitmaps的方式,直到“Ice Cream Sandwich”或那个时期。)

是的。如果Dalvik检测到内存严重短缺,它将开始大力运行GC。这时你的应用程序(以及其他应用程序)就会开始“挂起”。 - Rusheel Jain
这要看情况。如果是垃圾回收策略的问题,垃圾回收器会尽其所能在抛出OOM之前释放内存。如果未完成的对象导致问题,你可能会遇到麻烦——finalizer必须在独立于GC的线程上运行,因此托管堆不能等待它们运行。一般来说,在OOM之前,GC会有些抖动,这应该允许finalizer完成,并且在应用程序框架本身中不应该有任何疯狂的本机引用到大缓冲区。 - fadden

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接