Dalvik VM进程释放系统RAM吗?

时间:2014-01-10 16:39:58

标签: android memory-management dalvik

Android开发者文档,作为Project Svelte的一部分(座右铭:“你曾尝试将Bugdroid装入紧身牛仔裤吗?!?”),在Managing Your App's Memory上有一个页面。它包含:

  

当用户导航到其他应用并且您的用户界面不再可见时,您应该释放仅由您的用户界面使用的所有资源。此时释放UI资源可以显着提高系统缓存进程的容量,从而直接影响用户体验的质量。

  

TRIM_MEMORY_RUNNING_LOW:您的应用正在运行且不被视为可用,但设备的内存运行速度要低得多,因此您应该释放未使用的资源以提高系统性能(这会直接影响应用的性能)。

之类的。

然而,只有“释放资源”实际上会以某种方式影响系统RAM,这些才有意义。

我的印象是Dalvik VM的行为与Java VM的行为相同(或者“如果他们在我不看的时候更改了它”,可能会“做”)。 AFAIK,Java VM分配系统RAM以增加堆大小但从不释放它 - 一旦分配,只要进程运行,它仍然是堆空间的一部分。

如果Dalvik VM的行为方式相同,那么我无法看到增加过程中未分配堆空间的数量会对整体系统性能产生任何影响。现在,为我们的进程释放堆空间是一件好事,也许这样做会降低我们将来需要更多系统RAM的可能性......但这不是文档所暗示的。文档指出“此时释放UI资源可以显着提高系统缓存进程的容量”;它没有说“此时释放UI资源没有立竿见影的效果,但将来有助于减少应用程序的系统RAM占用空间”。

现在,如果指示告诉我们释放通过NDK分配的内存,那将是有意义的,因为它发生在Dalvik堆之外并且会影响系统RAM。但是文档没有得出这种区别。

除了终止进程之外,Dalvik VM是否实际将已分配的RAM释放回系统?如果是的话,何时?并且,在较小的程度上,考虑到垃圾收集器是非压缩和非复制的,它是如何完成的?

谢谢!

1 个答案:

答案 0 :(得分:29)

是。基本的想法是,如果有一个没有任何内容的4K页面,页面将返回到系统。

在VM中执行此操作的功能在dalvik/vm/alloc/HeapSource.cpp中称为trimHeaps()。您可以使用mspace_trim()来查看它,它使用OS调用来取消不再需要的块(请参阅malloc.c中第1203行附近的malloc_trim()注释)。然后它使用mspace_inspect_all()遍历堆,每个区域调用releasePagesInRange()。回调测试是否传递了一个没有分配的区域,如果是,则将边界截断为4K对齐。如果结果不为空,我们知道该区域跨越一个或多个物理4K页面,可以使用madvise(MADV_DONTNEED)将其返回给系统。

trimHeaps()从几个地方调用,最值得注意的是gcDaemonThread(),它将在并发GC后五秒钟启动调整。如果并发GC在五秒钟之前发生,计时器就会重置,这个想法是,如果我们正在进行GC操作,那么VM正忙于分配,这种空闲时间修剪将适得其反。

由于Dalvik GC不进行压实,因此效果不尽如人意。碎片往往随着时间的推移而逐渐增加,因此流程持续的时间越长,情况就越糟糕。应用程序框架可以“回收”长期服务以缓解这种情况。