Dalvik VM进程是否释放系统RAM?

作为Project Svelte的一部分(格言:“你曾经尝试把Bugdroid变成紧身牛仔裤?!?”)的一部分,Android开发者文档有一个关于pipe理你的应用程序内存的页面。 它包含:

当用户导航到不同的应用程序,并且您的用户界面不再可见时,您应该释放只有您的用户界面使用的任何资源。 此时释放UI资源可以显着增加系统对caching进程的容量,这直接影响用户体验的质量。

和:

TRIM_MEMORY_RUNNING_LOW :您的应用程序正在运行,但不被认为可以杀死,但是设备运行的内存要低得多,所以您应该释放未使用的资源来提高系统性能(这会直接影响您应用程序的性能)。

等等。

但是,这只有在“释放资源”以某种方式影响系统RAM时才有意义。

我的印象是,Dalvik虚拟机像Java虚拟机一样行事(或者可能是“做”了,如果改变的话,我不看)。 AFAIK,Java虚拟机分配系统RAM来增加堆大小,但从不释放 – 一旦分配,只要进程运行,它仍然是堆空间的一部分。

如果Dalvik虚拟机的行为方式相同,那么我看不到在我们的进程中增加未分配的堆空间的数量会如何影响整个系统的性能。 现在,为我们的进程释放堆空间是一件好事,也许这样做会降低我们将来需要更多系统RAM的可能性……但这不是文档所暗示的。 该文档指出“此时释放UI资源可以显着提高系统对caching进程的处理能力”; 它并没有说“目前释放UI资源没有直接影响,但将有助于减less未来应用程序的系统RAM占用空间”。

现在,指令告诉我们释放通过NDK分配的内存,这是有道理的,因为这发生在Dalvik堆外,并会影响系统RAM。 但是文档没有提供这种区别。

Dalvik虚拟机实际上释放分配的RAM回到系统,除了终止进程? 如果是,什么时候? 而且,考虑到垃圾收集器是非压缩的和非复制的,在较小程度上,这是如何完成的?

谢谢!

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

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

trimHeaps()是从几个地方调用的,最显着的是gcDaemonThread() ,它将在并发GC之后五秒钟开始修剪。 如果在5秒钟之前发生并发的GC,定时器会被重置,这个想法是,如果我们是GCing,那么VM正在忙于分配,这种空闲时间调整将会适得其反。

由于Dalvik GC不做压缩,所以效果不如以前。 随着时间的推移,碎片化会逐渐增多,所以在一个进程所处的时间越长的情况下,情况就越糟糕。 应用程序框架可以“回收”长期服务来缓解这种情况。