首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >如何针对普通基准调优Java GC?

如何针对普通基准调优Java GC?
EN

Stack Overflow用户
提问于 2012-05-16 15:04:01
回答 3查看 367关注 0票数 4

我正在试着调优GC,这样它就不会在短时间的基准测试中发挥作用。

为此,我试图将年轻一代设置为尽可能大,并确保我创造的垃圾比伊甸园的大小更少。

我使用了以下参数:

代码语言:javascript
运行
复制
java -Xmx1g -Xms1g -Xmn1g -XX:NewSize=1000m -XX:MaxNewSize=1g -XX:SurvivorRatio=10000 -verbose:gc Main

但是由于某些原因,当VM内存只有300M时,我仍然可以看到完整的GC日志,我是否遗漏了任何JVM调优?

EN

回答 3

Stack Overflow用户

回答已采纳

发布于 2012-05-16 15:11:41

如果你释放大量的对象,GC仍然会运行,这不是纯粹的等待,直到你用完了所有分配的空间,如果它这样做了,当它确实运行时,它将导致严重的GC抖动。

你应该看看你对对象处理的使用,以及你是否可以更有效率。看一看LMAX disrupter模式,了解如何通过更新对象值来重用对象,而不是释放和替换对象本身。

也就是说,这是一篇关于优化GC - http://developer.amd.com/documentation/articles/pages/4EasyWaystodoJavaGarbageCollectionTuning.aspx的非常好的文章

票数 1
EN

Stack Overflow用户

发布于 2012-05-16 18:43:59

你的存活率非常重要,有了10000,你就告诉JVM一个存活者空间是伊甸园大小的10000倍。

From documentation

如果幸存空间太小,则复制集合溢出将直接溢出到终身代。如果幸存空间太大,它们将是无用的空空间。在每次垃圾收集时,虚拟机都会选择一个阈值次数,该次数可以在对象保留之前复制该对象。选择这个阈值是为了让幸存者保持半满。命令行选项-XX:+PrintTenuringDistribution可用于显示此阈值和新一代对象的年龄。它对于观察应用程序的生命周期分布也很有用。

因此,很明显,在存活者空间比率如此之低的情况下,您的对象直接存储在终身代中。

当终身期已满时,发生了主要收集,这就是为什么您在日志中看到[Full GC...]的原因。

如果你想让年轻一代有更大的用武之地:

代码语言:javascript
运行
复制
-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?)

  • 如果在年轻层代中分配失败,并且对象是不包含任何对象引用的大型数组,则可以将其直接分配到旧层代中。在某些选择的情况下,此策略旨在通过从老一代中分配来避免年轻一代的集合。阈值大小为64k字。
票数 2
EN

Stack Overflow用户

发布于 2012-05-17 15:22:39

您可以获得完整的GC,因为您的永久空间已被填满(大型对象直接放入永久空间)

我通常尝试4- 24 GB的eden大小,但确保永久空间的大小为0.5 -2 GB。

票数 2
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/10613563

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档