Android开发人员文档(作为Svelte项目的一部分)(座右铭:“您曾经尝试将Bugdroid安装到紧身牛仔裤上吗?!?”),上有一个页面“管理应用程序的内存”。它包含了:
当用户导航到其他应用程序且您的UI不再可见时,您应释放仅由UI使用的所有资源。此时释放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释放回系统?如果是这样,什么时候?而且,在较小程度上,考虑到垃圾收集器是非压缩且非复制的,该如何完成?
谢谢!
是。基本思想是,如果有一个4K页面,上面没有任何内容,则该页面将返回给系统。
trimHeaps()
在dalvik / vm / alloc / HeapSource.cpp中,在VM中执行此功能的函数称为。您可以使用看到它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不会进行压缩,因此效果不如预期。随着时间的流逝,碎片趋于堆积,因此,随着过程寿命的延长,情况可能会变得更糟。应用程序框架可以“回收”长期存在的服务来缓解这种情况。
本文收集自互联网,转载请注明来源。
如有侵权,请联系[email protected] 删除。
我来说两句