4

在此链接上,据说:

这些暂停是压缩堆以释放空间的必然要求的结果。收集器使用不同的策略来延迟这些事件,但是对于所有商业可用的收集器来说,压缩是不可避免的。

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

我知道为 Java 应用程序保持恒定的内存占用并不容易,但使用正确的分析工具、引导程序和纪律是可能的。

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

编辑:通过不断的内存占用,我的意思是steady stateAjay George 提到的,当没有更多的对象被创建或取消引用时。如果你继续创建对象,你最终会耗尽内存,如果你继续取消引用对象,你最终会触发 GC。所以最终目标是启动、预热、强制进行完整的 GC,然后进入稳定状态以进行生产时间。

4

3 回答 3

2

我的印象是,如果你保持应用程序的内存占用不变,那么就不需要发生 GC 压缩,换句话说,只有在你不断添加和收集对象时才会发生。

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

那么假设 Java 应用程序可以在没有任何 GC 引入的延迟(换句话说,没有 GC 暂停)的情况下运行,这不是合理的吗?

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

话虽如此,使用 Azul 的 Pauseless Collection 算法,这也许是可能的。这里有一个很好的讨论。

于 2012-11-21T05:46:57.593 回答
1

不,压缩并不是真正必要的,许多垃圾收集器并不压缩,CPython 就是一个例子,对象永远不会在内存中移动。

压缩垃圾收集器确实提供了一个很大的优势——它们可以取回碎片化的内存。

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

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

于 2013-01-22T16:37:16.833 回答
0

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

我不具体了解 Java(这可能取决于您使用的 JVM),但大多数语言根本不会调用 GC,除非您正在分配或释放内存。很多时候,它只是在分配期间(因为这是唯一需要更多空闲内存的时候),当然也是在显式调用时。

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

于 2014-01-03T07:31:44.390 回答