我正在试着调优GC,这样它就不会在短时间的基准测试中发挥作用。
为此,我试图将年轻一代设置为尽可能大,并确保我创造的垃圾比伊甸园的大小更少。
我使用了以下参数:
java -Xmx1g -Xms1g -Xmn1g -XX:NewSize=1000m -XX:MaxNewSize=1g -XX:SurvivorRatio=10000 -verbose:gc Main
但是由于某些原因,当VM内存只有300M时,我仍然可以看到完整的GC日志,我是否遗漏了任何JVM调优?
发布于 2012-05-16 15:11:41
如果你释放大量的对象,GC仍然会运行,这不是纯粹的等待,直到你用完了所有分配的空间,如果它这样做了,当它确实运行时,它将导致严重的GC抖动。
你应该看看你对对象处理的使用,以及你是否可以更有效率。看一看LMAX disrupter模式,了解如何通过更新对象值来重用对象,而不是释放和替换对象本身。
也就是说,这是一篇关于优化GC - http://developer.amd.com/documentation/articles/pages/4EasyWaystodoJavaGarbageCollectionTuning.aspx的非常好的文章
发布于 2012-05-16 18:43:59
你的存活率非常重要,有了10000,你就告诉JVM一个存活者空间是伊甸园大小的10000倍。
From documentation:
如果幸存空间太小,则复制集合溢出将直接溢出到终身代。如果幸存空间太大,它们将是无用的空空间。在每次垃圾收集时,虚拟机都会选择一个阈值次数,该次数可以在对象保留之前复制该对象。选择这个阈值是为了让幸存者保持半满。命令行选项-XX:+PrintTenuringDistribution可用于显示此阈值和新一代对象的年龄。它对于观察应用程序的生命周期分布也很有用。
因此,很明显,在存活者空间比率如此之低的情况下,您的对象直接存储在终身代中。
当终身期已满时,发生了主要收集,这就是为什么您在日志中看到[Full GC...]
的原因。
如果你想让年轻一代有更大的用武之地:
-XX:NewRatio=1
这意味着eden和survivor空间的总大小将是整个堆大小的一半。(我想你不能有一个更大的年轻一代)
如果你已经设置了-XX:NewSize
,你也不需要设置-Xmn
,-Xmn
从1.4开始就是一样的了。我猜你不想从上面用-XX:MaxNewSize
绑定年轻的gen,默认值是无限制的。但是将年轻一代的大小设置为与最大堆大小相同的值意味着您不会为老一代腾出空间,因此我猜JVM将调整各代的大小。
总而言之,也有一些情况下,分配可以直接发生在终生一代。(Do objects ever get allocated directly into the old generation?)
发布于 2012-05-17 15:22:39
您可以获得完整的GC,因为您的永久空间已被填满(大型对象直接放入永久空间)
我通常尝试4- 24 GB的eden大小,但确保永久空间的大小为0.5 -2 GB。
https://stackoverflow.com/questions/10613563
复制相似问题