【问题标题】:JVM and GC tuning - theory for no Full GCJVM 和 GC 调优 - 没有 Full GC 的理论
【发布时间】:2011-06-03 10:58:46
【问题描述】:

我有两种类型的对象的大规模应用程序:长期(缓存)和短期(请求-处理-响应)。理论上,用这种类型的应用,我觉得配置Young vs Old空间是可以的,所以Old空间消耗是恒定的,导致没有Full GC。

我更改了 newSize-maxNewSize 参数,但是,旧堆继续上升,直到 Full GC。每次 Full GC 后,消耗下降到 20%(缓存占 20%)。出于某种原因,我的对象进入了旧空间。我有两个怀疑为什么要搬到旧空间:

  • 根据这篇文章:http://chaoticjava.com/posts/gc-tips-and-memory-leaks/ 它被告知如果您分配了大对象,这些对象会直接进入旧空间。这是真的吗,如果是的话,是否有JVM Option参数可以为Young空间设置对象大小阈值?

  • 如果我正确理解了这个过程,对象会在 To-From 生存部分之间切换,然后再移动到旧部分。是否有参数可以设置在移动到旧空间之前要在 To 和 From 之间完成多少次切换?

还有什么建议吗?

谢谢, 阿马尔

【问题讨论】:

    标签: java garbage-collection jvm performance


    【解决方案1】:

    听起来你的幸存者空间不够大。您需要使它们足够大,以至于不需要收集任何对象。一个对象只进出幸存者空间一次。

    如果您要分配大对象,您是否可以为它们使用对象池以避免对它们进行 GC。您是否考虑过为您的请求/处理/响应数据使用对象池?例如一个简单的方法是使用 ThreadLocal。

    您是否尝试过 G1 收集器,该收集器旨在逐步收集您的所有内存并减少完整 GC 的大命中率。

    【讨论】:

      【解决方案2】:

      你确定老年代的增长只是没有缓存对象吗?除非您的缓存是固定的并且永远不会更改,否则您将不断地添加它。由于已经到达老年代的对象从该缓存中过期,它们将留在内存中直到下一次完整的 GC。

      并发标记清除收集器完全消除了完整 GC 的长时间停顿,我的运气要好得多。这需要一些调整,并且可能因应用程序而异。以下是我们用来运行 24GB 64 位 JVM 的方法,其 GC 暂停时间为 1 秒级,同时每秒处理 100 多个页面请求并具有大缓存:

      -Xms24g -Xmx24g -XX:+UseCompressedOops -XX:NewRatio=4 -XX:SurvivorRatio=8    
      -XX:+UseConcMarkSweepGC -XX:+UseParNewGC -XX:+DisableExplicitGC  
      -XX:+UseCMSInitiatingOccupancyOnly -XX:+CMSClassUnloadingEnabled  
      -XX:+CMSScavengeBeforeRemark -XX:CMSInitiatingOccupancyFraction=68
      

      【讨论】:

      • WhiteFang34 我是否需要从我的 JVM 参数中删除以下选项:-Dsun.rmi.dgc.client.gcInterval=3600000 和 -Dsun.rmi.dgc.server.gcInterval=3600000 如果我要做什么试试你的参数?
      • @Yoldar-Zi 你可以保留这些 RMI 选项。
      【解决方案3】:

      有没有参数可以设置多少 在 To 和 From 之间切换 is to be 在搬到旧空间之前完成了吗?

      是的,-XX:MaxTenuringThreshold

      此开关决定了对象在升级到老一代之前在“From”和“To”Survivor 空间之间跳跃的次数。 Java 6 的最大值为 15,早期 JDK 的最大值为 31。 The default value is 15 for the parallel collector and is 4 for CMS collectors.

      来自 Sun JVM GC 文档,

      使用 -XX:MaxTenuringThreshold=0 移动 一个在年轻人中幸存下来的物体 立即生成集合到 终生一代。

      如果你想做相反的事情,如果你没有设置这个值,它将是默认值,这足以决定对象是否需要进入旧 - 提供 em> 正如@Peter 所说,幸存者足够大,可以容纳这些物体。

      您的 SurvivorRatio 设置为多少?你的总堆是多少?

      【讨论】:

        【解决方案4】:

        对象生命周期特征在这里起着至关重要的作用。重要的调整旋钮是幸存者空间的大小、任期阈值和年轻代的大小。从策略上讲,我们希望对象年轻时死去,所以如果次要集合之间有足够的差距,很多对象将在年轻代中死去。此外,我们可以配置任期阈值,以便对象在幸存者空间中保留所需数量的集合。

        由于我们在幸存者空间中保留大量活动对象,并不断将它们从一个空间复制到另一个空间以进行多次次要 GC,因此增加了次要 GC 的成本。

        保持较大的年轻代自然会增加连续次要收集之间的差距,并为对象提供更多死亡时间。

        人们可以通过试验这些变量来达到适当的平衡,以减少对老年代的对象提升,同时考虑可接受的年轻代暂停

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          相关资源
          最近更新 更多