【问题标题】:Under What Conditions Does ART Compact the Heap?ART 在什么条件下压缩堆?
【发布时间】:2016-09-28 20:20:42
【问题描述】:

Android 5.0+ 中 ART 运行时的一个被吹捧的功能是堆压缩,以减少堆碎片。碎片堆可以更轻松地获得OutOfMemoryErrors,因为可能没有一个连续的空闲内存块足以满足您的需求,即使整个堆有足够的可用空间。

我了解,当应用移动到后台时,会发生这种情况,基于 Google 会议演示等。但是,我可以在 the documentation 中找到的唯一声明是:

同构空间压缩是从空闲列表空间到空闲列表空间的压缩,这通常发生在应用程序移动到无法察觉的暂停进程状态时。这样做的主要原因是减少 RAM 使用和对堆进行碎片整理。

从技术上讲,尚不清楚“暂停不可察觉的进程状态”究竟是什么意思。

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

【问题讨论】:

  • 只是验证你已经阅读了source.android.com/devices/tech/dalvik/gc-debug.html,它谈到了“堆压缩”Currently, the event that triggers heap compaction is ActivityManager process-state changes. When an app goes to background, it notifies ART the process state is no longer jank “perceptible.”
  • @MorrisonChang:不,我错过了那个页面——谢谢!这有帮助,但我不知道如何解释“应用程序进入后台”。如果字面上指的是IMPORTANCE_BACKGROUND,那么即使有一个正在运行的服务也可能会阻塞堆压缩。
  • 似乎您只是想得到保证。您的后台任务相关服务是否遇到任何问题?如果你能想出一个与性能相关的实际问题,那就太好了。关于服务,与前台任务相比,它们的优先级较低,并且从一开始就存在,就像手机内存不足时您的服务将被终止或阻止一样。要深入挖掘,您可以阅读有关粘性 CMS 和对象图的信息,会有所帮助
  • “看起来你只是想得到保证”——我只是想能够告诉开发人员会发生什么,因为这种行为是无证的。 “当手机内存不足时,您的服务将被终止或阻止” - 不,它不会。 Android 终止进程以释放系统 RAM; Android 不会破坏单个组件。此外,这与问题并不严格相关。

标签: android


【解决方案1】:

拼图。

据我所知,ART 将压缩任何暂停 2-3 秒的内容,暂停意味着当前不在后台运行,因此是活动,但不运行服务。它还可以即时压缩,或者在应用处于前台时同时压缩。

Currently, the event that triggers heap compaction 是 ActivityManager 进程状态的变化。当应用程序进入后台时,它会通知 ART 进程状态不再是“可感知的”卡顿。这使 ART 能够执行导致长时间应用程序线程暂停的事情,例如压缩和监控通缩。

Chet Hasse 状态:

Garbage Collection
ART 带来了改进的垃圾收集动态。一方面,ART 是一个移动的收藏家;当应用程序中的长时间暂停不会影响用户体验时(例如,当应用程序在后台并且不播放音频时),它能够压缩堆。此外,对于像位图这样的大对象,还有一个单独的堆,可以更快地为这些大对象找到内存,而无需费力地穿过可能碎片化的常规堆。 ART 中的停顿时间通常在 2 到 3 毫秒之间。

据我所知,应用程序中的任何暂停对 ART GC 来说都是公平的游戏。

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

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

source code here should have the answer。他们正在使用像InJankPerceptibleProcessState() 这样的命名并试图通过这个,因为你可能已经有了自己。

阅读它,当/如果我找到明确的答案时会更新答案。

【讨论】:

  • “我怀疑应用程序需要完全暂停所有服务,等等才能进行压缩”——我希望压缩会被前台服务阻止,而不是常规的非前台服务.但这正是问题的症结所在。作为开发人员,我们真的应该知道我们可能会做(或不做)哪些事情会影响 ART 是否可以压缩堆。如果答案是您所怀疑的,即有任何服务会阻塞堆压缩,那么了解这一点很重要。
  • 哦,请不要把我的评论当成投诉!我只是在澄清问题,仅此而已。非常感谢您的帮助!
  • @CommonsWare 只是我的 2 美分,当应用程序在后台时意味着没有完全关闭我认为 ART 仍然可以压缩堆,我在分析应用程序中的堆转储时看到它发生了
  • @Yvette 我没有检查是否需要检查,但我的前台应用程序是多进程的,所以我猜它会在不再需要时杀死我的 UI 进程
【解决方案2】:

同构空间压缩是从空闲列表空间到空闲列表空间的压缩,这通常发生在应用程序移动到无法察觉的暂停进程状态时。这样做的主要原因是减少 RAM 使用和对堆进行碎片整理。

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

【讨论】:

  • 这就是我的问题。您可以通过阅读问题并查看引用的段落来判断。
  • @Jamil Hasnine Tamim 。很高兴得到大胆的回答。亲爱的,您甚至知道 CommonsWare 是谁.. !!他是一个传奇人物......如果他问一些问题(这本身非常罕见!),你应该在回答之前不要思考两次,而是思考超过 100 次!无论如何,对尝试的赞誉!...还有一件事,我不是反对您的人...您可能会想,这就是我在这里提到的原因
  • @CommonsWare 对不起兄弟...我是堆栈中的新手,但我尝试提供一些信息而不是确切的答案!我道歉..并等待正确的答案。
  • @Stallion 想知道...如果他是传奇人物,那么很荣幸得到他的回复...谢谢
【解决方案3】:

实际上,您可以通过衡量应用程序的空闲时间。如果在 TextWatcher/OnKeylistner 中捕获了任何事件,则启动空闲计时器并停止,如果您的应用程序在后台并且没有调用这些事件,则最好被 GC 收集。

此外,这种堆收缩是基于事件和基于优先级的。例如,如果从来没有用户需要内存的场景,操作系统甚至不会这样做。

就优先级而言,对于垃圾回收,它会寻找没有后台服务的后台应用程序,然后是有后台服务的应用程序,最后是前台应用程序。

【讨论】:

  • 这个问题与应用的空闲时间无关。请提供任何证据表明堆压缩是“基于优先级的”。此外,请提供任何证据证明堆压缩是在前台应用程序上执行的,因为文档明确说明了其他情况。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2011-06-05
  • 2014-12-07
  • 1970-01-01
  • 1970-01-01
  • 2015-06-07
  • 2012-03-08
  • 2013-05-17
相关资源
最近更新 更多