Android 5.0+中ART运行时的一个受欢迎的功能是堆压缩,以减少堆碎片。碎片堆可以更容易地获得OutOfMemoryErrors
,因为可能没有足够大的单个内存空间块足以满足您的需求,即使堆总体上有足够的可用空间。
据我所知,当应用移动到后台时会出现这种情况,基于Google会议演示文稿等。但是,我在the documentation中可以找到的唯一声明是:
同构空间压缩是自由列表空间,用于自由列出空间压缩,这通常在应用程序移动到暂停不可察觉的进程状态时发生。这样做的主要原因是减少RAM使用量并对堆进行碎片整理。
目前还不清楚确切地说是什么"暂停不可察觉的过程状态"在技术上意味着。
假设某个应用目前没有任何前台活动。开发人员可能做了哪些事情可能会阻止该应用程序进程的堆压缩?例如,是否有前台服务块堆压缩?
答案 0 :(得分:8)
把拼图的各个部分放在一起。
根据我的判断,ART会压缩暂停2-3秒的任何内容,暂停时意味着当前没有在后台运行,所以活动,但没有运行服务。它还可以在应用程序处于前台时动态压缩,或同时压缩。
Currently, the event that triggers heap compaction是ActivityManager进程状态更改。当应用程序进入后台时,它会通知ART,进程状态不再“明显”。这使ART能够执行导致长应用程序线程暂停的事情,例如压缩和监视器通缩。
<强> Garbage Collection 强>
ART带来了改进的垃圾收集动态。首先,ART是一个移动的收藏家;当应用程序中的长时间停顿不会影响用户体验时(例如,当应用程序在后台并且不播放音频时),它能够压缩堆。此外,对于大型对象(如位图),还有一个单独的堆,可以更快地为这些大型对象查找内存,而无需浏览可能碎片化的常规堆。 ART的停顿时间通常为2-3ms。
从我看到的应用中的任何停顿都是ART GC的公平游戏。
我怀疑应用程序需要完全暂停所有服务,以便发生压缩,因为它重新分配堆的内存地址,并且为此发生,它不能改变。由于这个在应用程序暂停期间而不是在运行中采用的更大的压缩是堆的动态重新排列。可以在较小的暂停中进行的唯一更改是在不再使用的进程上重新路由某些地址。
虽然这是一个有根据的猜测,但不是确定的,我会努力获得更多信息。
source code here should have the answer。他们正在使用像InJankPerceptibleProcessState()
这样的命名并试图趟过这个,因为你可能已经拥有了。
阅读它,如果我找到明确答案,将更新答案。
答案 1 :(得分:0)
同构空间压缩是自由列表空间,用于自由列出空间压缩,这通常在应用程序移动到暂停不可察觉的进程状态时发生。这样做的主要原因是减少RAM使用量并对堆进行碎片整理。
来源:https://developer.android.com/studio/profile/investigate-ram.html#LogMessages
答案 2 :(得分:-1)
实际上,您可以通过测量应用的空闲时间。启动空闲计时器并停止,如果在TextWatcher / OnKeylistner中捕获了任何事件,如果您的应用程序在后台并且没有调用这些事件,则最好由GC收集。
此堆收缩也是基于事件和基于优先级的。例如,如果从未有用户需要内存的情况,OS甚至不会这样做。
就优先级而言,对于垃圾收集,它会查找没有后台服务的后台应用程序,然后查找具有后台服务的应用程序以及最后的前台应用程序。