在什么条件下ART紧凑堆?

Com*_*are 31 android

Android 5.0+中ART运行时的一个受欢迎的功能是堆压缩,以减少堆碎片.碎片堆可以变得OutOfMemoryErrors更容易,因为可能没有足够大的单个内存空间块足以满足您的需求,即使堆总体上有足够的可用空间.

据我所知,这会在应用移动到后台时发生,基于Google会议演示文稿等.但是,我在文档中可以找到的唯一声明是:

同构空间压缩是自由列表空间,用于自由列出空间压缩,这通常在应用程序移动到暂停不可察觉的过程状态时发生.这样做的主要原因是减少RAM使用量并对堆进行碎片整理.

从技术上讲,目前尚不清楚"暂停不可察觉的过程状态"究竟意味着什么.

假设一个应用程序目前没有任何前台活动.开发人员可能做了哪些事情可能会阻止该应用程序进程的堆压缩?例如,是否有前台服务块堆压缩?

Yve*_*omb 9

把拼图的各个部分放在一起.

从我可以确定的,ART将压缩暂停2-3秒的任何东西,并暂停它意味着当前不在后台运行,所以活动,但不运行服务.它还可以在应用程序处于前台时动态压缩,或同时压缩.

目前,触发堆压缩的事件是ActivityManager进程状态更改.当应用程序进入后台时,它会通知ART,进程状态不再是"可感知的".这使ART能够执行导致长应用程序线程暂停的事情,例如压缩和监视器通缩.

Chet Hasse说:

垃圾收集
ART带来了改进的垃圾收集动态.首先,ART是一个移动的收藏家; 当应用程序中的长时间停顿不会影响用户体验时(例如,当应用程序在后台并且不播放音频时),它能够压缩堆.此外,对于大型对象(如位图),还有一个单独的堆,可以更快地为这些大型对象查找内存,而无需浏览可能碎片化的常规堆.ART中的停顿通常在2-3ms的范围内.

从我可以看到应用程序中的任何暂停是ART GC的公平游戏.

我怀疑应用程序需要完全暂停所有服务,以便发生压缩,因为它重新分配堆的内存地址,并且为此发生,它不能改变.由于这个在应用程序暂停期间而不是在运行中采用的更大的压缩是堆的动态重新排列.可以在较小的暂停中进行的唯一更改是在不再使用的进程上重新路由某些地址.

虽然这是一个有根据的猜测,但不是确定的,我会努力获得更多信息.

这里源代码应该有答案.他们正在使用命名,InJankPerceptibleProcessState()并试图趟过这个,因为你可能已经有了自己.

阅读它,如果我找到明确的答案,将更新答案.


Jam*_*mim 0

均匀空间压缩是空闲列表空间到空闲列表空间的压缩,通常在应用程序进入暂停、难以察觉的进程状态时发生。这样做的主要原因是减少 RAM 使用量和对堆进行碎片整理。

来源: https: //developer.android.com/studio/profile/investigate-ram.html#LogMessages

  • 这就是我的问题。您可以通过阅读问题并查看引用的段落来判断这一点。 (4认同)
  • @贾米尔·哈斯宁·塔米姆。很高兴有大胆的回答。亲爱的你知道 CommonsWare 是谁吗..!! 他是一个传奇人物……如果他问了一些问题(这本身就非常罕见!),你应该在回答之前思考超过 100 次而不是三思而后行!无论如何,对这次尝试表示赞扬!...还有一件事,我不是那个对你投反对票的人...也许你可能会想,这就是我在这里提到的原因 (2认同)