压缩对于所有JVM GC实现来说真的是不可避免的吗?

时间:2012-11-21 05:29:03

标签: java garbage-collection real-time latency low-latency

关于这个link,据说:

  

这些停顿是不可避免的紧凑要求的结果   堆来释放空间。收藏家使用不同的策略   延迟这些事件,但压缩是不可避免的所有商业   可用的收藏家。

我的印象是,如果你保持应用程序的内存占用不变,那么就不需要进行GC压缩,换句话说,只有在你不断添加和收集对象时才会发生这种情况。如果你有足够大的堆,有足够的可用空间,为什么你不需要在不创建任何漏洞时压缩(即不产生任何垃圾)?

我知道为Java应用程序保留一个恒定的内存占用并不容易,但可以通过正确的分析工具,引导和规范来实现。

因此,假设具有恒定的内存占用量,Java应用程序可以在没有任何GC引入的延迟的情况下运行,换句话说,没有GC暂停,这是不合理的吗?

编辑:通过常量内存占用,我指的是Ajay George提到的steady state,当没有更多对象被创建或取消引用时。如果继续创建对象,最终会耗尽内存,如果继续取消引用对象,最终会触发GC。因此,最终目标是启动,预热,强制完整GC,然后进入稳定状态进行生产。

3 个答案:

答案 0 :(得分:2)

  

我的印象是,如果你保持内存足迹   你的应用程序常量,那么就不需要GC压缩了   换句话说,只有你继续添加和才会发生   收集物品。

当您的对象被取消引用(符合垃圾收集条件)时,可以进行压缩。 这是因为您开始对堆进行分段,就像您的硬盘驱动器碎片一样。

  

因此假设具有恒定的内存占用率是不合理的   Java应用程序可以在没有任何GC引入的延迟的情况下运行   换句话说,没有GC暂停?

GC引入的延迟是使用GC算法类型的结果。它与具有恒定存储器占用空间的概念正交。好吧,如果您正在考虑您的应用程序不创建或取消引用对象并且可能获得某种steady state的情况。理想情况下情况并非如此,因为大多数对象都是短暂的。

话虽如此,使用Azul的Pauseless Collection算法,这可能是可能的。 对here进行了很好的讨论。

答案 1 :(得分:1)

不,压缩并不是必需的,很多垃圾收集器都不紧凑,一个典型的例子就是CPython,对象永远不会在内存中移动。

压缩垃圾收集器确实提供了一个很大的优势 - 它们会得到碎片回忆。

如果你没有压缩,你的进程内存使用率永远不会下降,因为如果一个4K页面中仍然有一个16字节的None,则无法释放它。稳定状态在这里没有帮助,因为在垃圾收集系统中,稳定状态意味着生成和回收大量垃圾。稳态是等量的。 CPython通过对象生成来处理(新创建的对象更有可能成为垃圾)。

最后有增量垃圾收集器,或者如果你进行了前沿研究,那么暂停的并发硬件辅助垃圾收集器http://www.cs.purdue.edu/homes/hosking/ismm2000/papers/heil.pdf,一个可商用的http://www.azulsystems.com/products/zing/whatisit

答案 2 :(得分:0)

我相信当他们说“压缩是不可避免的”时他们的意思是他们只是意味着一个好的GC最终会对典型的内存分配模式执行压缩。

我并不特别了解Java(并且它可能取决于您使用的JVM),但除非您正在分配或取消分配内存,否则大多数语言都不会调用GC。通常只在分配期间(因为这是唯一需要更多可用内存的时间),当然也是明确调用时。

因此,对于你的“稳定状态”的相当奇怪的定义,其中没有分配发生并且甚至没有生成垃圾,如果它已经完成了完整的收集/压缩,则根本没有理由调用GC。在这种情况下,试图压缩堆当然会浪费时间。