上下文:64位Oracle Java SE 1.8.0_20-b26
超过11个小时,我正在运行的java8应用程序已累积Tenured generation中的对象(接近25%)。因此,我手动点击了jconsole中的Perform GC
按钮,您可以看到图表右侧堆内存的急剧下降。除了XX:NewRatio=2
之外,我没有启用任何特殊的VM选项。
为什么GC不能清理终生代?
答案 0 :(得分:3)
这是完全预期的理想的行为。 JVM通过及时执行Minor GC成功避免了主要GC。根据定义,小型GC不接触Tenured Generation,而且分代垃圾收集器背后的关键理念是这种模式正好会出现。
你应该非常满意你的应用程序如何哼唱。
答案 1 :(得分:2)
为什么GC不能清理终生代?
因为它不需要。
看起来您的应用程序正在以相对较慢的速度累积终身垃圾,并且仍然有足够的空间用于终身对象。 “吞吐量”收集器通常仅在空间填满时运行。就CPU使用率而言,这是最有效的......这是吞吐量收集器优化的。
简而言之,GC正在按预期工作。
如果您担心正在使用的内存量(因为未收集终端空间),您可以尝试使用较小的堆运行应用程序。但是,该图表明应用程序的初始行为可能与其稳态行为明显不同。换句话说,您的应用程序可能要求一个大堆开始。如果是这种情况,那么减小堆大小可能会使应用程序停止工作,或者至少使启动阶段变慢。
答案 2 :(得分:2)
吞吐量收集器的主要目标是,如其名称所示,吞吐量(通过GCTimeRatio
)。其次要目标是暂停时间(MaxGCPauseMillis
)。仅在tertiary goal时才考虑将内存占用率保持在较低水平。
如果你想要实现低堆大小,你将不得不放松其他两个目标。
您可能还希望降低MaxHeapFreeRatio
以允许JVM将内存返回给操作系统。