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

标签 android memory-management dalvik

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

When the user navigates to a different app and your UI is no longer visible, you should release any resources that are used by only your UI. Releasing UI resources at this time can significantly increase the system's capacity for cached processes, which has a direct impact on the quality of the user experience.

和:

TRIM_MEMORY_RUNNING_LOW: Your app is running and not considered killable, but the device is running much lower on memory so you should release unused resources to improve system performance (which directly impacts your app's performance).

等等。

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

我的印象是,Dalvik VM 的行为与 Java VM 一样(或者可能是“确实”,如果他们在我不注意时更改了它)。 AFAIK,Java VM 分配系统 RAM 以增加堆大小,但从不释放它——一旦分配,只要进程运行,它就一直是堆空间的一部分。

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

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

Dalvik VM 是否真的将分配的 RAM 释放回系统,而不是通过终止进程?如果有,什么时候?而且,在较小程度上,考虑到垃圾收集器是非压缩和非复制的,这是如何完成的?

谢谢!

最佳答案

是的。基本思路是,如果有4K页面没有任何内容,页面会返回给系统。

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

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

因为 Dalvik GC 不进行压缩,所以它的效果不如预期。 fragment 化往往会随着时间的推移而增加,因此过程存在的时间越长,情况可能会变得更糟。应用框架可以“回收”长期存在的服务来缓解这种情况。

关于android - Dalvik VM 进程是否会释放系统 RAM?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/21049715/

相关文章:

android - 响应式网页设计 : Android default browser "thinks" that he is larger than he is

java - 使用倒计时器功能防止这种情况发生

Android:编译错误:任务 ':app:compileDebugJava'执行失败

multithreading - 线程是否可以访问同一进程的其他线程的堆栈?

android - 如何使用 adb 工具调用 GC?

android - 何时何地调用 GC_CONCURRENT?

android - 无法让 Joda-time 在 Android 上运行。

java - 交换 Activity 后如何保持 countDownTimer 计数?

c++ - DH_free 精确行为

c - 在 C 中取消分配结构内部的内存