【发布时间】:2010-07-09 13:14:40
【问题描述】:
是否可以想象,Java 程序创建新对象的速率在某种程度上超过了这些对象在年轻代中被垃圾回收的速率?
...因此导致堆上的新对象越来越多,直到触发完整的 gc ?
我可以收集任何指标来识别/验证这种情况吗?
创建的对象的最长寿命约为 1 秒。大多数平均存活时间约为 400 毫秒。
谢谢。
【问题讨论】:
是否可以想象,Java 程序创建新对象的速率在某种程度上超过了这些对象在年轻代中被垃圾回收的速率?
...因此导致堆上的新对象越来越多,直到触发完整的 gc ?
我可以收集任何指标来识别/验证这种情况吗?
创建的对象的最长寿命约为 1 秒。大多数平均存活时间约为 400 毫秒。
谢谢。
【问题讨论】:
当 GC 启动并将对象从 Young 移出(到 S0 或 S1)时,死对象不会被复制并因此被丢弃。对象在 S0 和 S1 之间来回移动多次,直到它们死亡或它们变得足够老可以转移到旧空间。
S0和S1是Young(Eden)和Old空间之间的存储空间。
GC 运行了很长时间,有对象要复制,丢弃所有死对象。 Full GC 在实际需要回收内存时执行,示例对象需要从旧空间中删除。
清理 Young 空间最快的方法实际上是等到大多数对象都死了,因为这样你就不必复制那么多到 S0|S1 再复制到 Old。
所以填满内存,然后以更长的 GC 运行为代价,实际上比让 GC 以非常短的间隔运行更有效。这就是为什么你会看到你的记忆不断增长,直到它几乎充满,然后它又下降到几乎没有。
完整的 GC 是 StopTheWorld,这是在 Old 空间重新排列堆上的对象所需要的,在 Young 空间中不需要。如果年轻空间变满,则可以将快速对象提升到旧空间。这不是一个好案例,这就是您正在考虑的案例。
为避免 Full GC,您可以计算在 Young Space 中需要多少内存,并使用您必须确保对象在必要之前不被提升的创建率。还可以调整 S0 和 S1 空间的大小以及对象在它们最终进入旧空间之前在它们之间反弹的次数(需要删除 Full GC)。
Tuning Garbage Collection 上的这个链接不错,但有点旧了
【讨论】: