【问题标题】:Do Dalvik VM Processes Release System RAM?Dalvik VM 进程是否会释放系统 RAM?
【发布时间】:2014-01-29 17:52:34
【问题描述】:

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

当用户导航到其他应用并且您的 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 释放回系统,而不是通过终止进程?如果有,什么时候?而且,在较小程度上,考虑到垃圾收集器是非压缩和非复制的,这是如何完成的?

谢谢!

【问题讨论】:

    标签: android memory-management dalvik


    【解决方案1】:

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

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

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

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

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2011-01-26
      • 1970-01-01
      • 2015-08-08
      • 1970-01-01
      • 2020-04-09
      • 2019-11-02
      相关资源
      最近更新 更多