【问题标题】:Young generation is tiny despite NewRatio=2尽管 NewRatio=2,年轻一代还是很小
【发布时间】:2013-04-21 09:57:35
【问题描述】:

在某些时候,我的应用程序开始创建大量临时数组,这是预期的行为,我想为年轻代提供大量空间,因此临时数组不会被提升为终身代。

JVM 选项: java -Xmx240g -XX:+UseConcMarkSweepGC -XX:NewRatio=2 -XX:+PrintGCTimeStamps -verbose:gc -XX:+PrintGCDetails

在某些时候,我的 GC 日志开始看起来像这样:

800.020: [GC 800.020: [ParNew: 559514K->257K(629120K), 0.1486790 secs] 95407039K->94847783K(158690816K), 0.1487540 secs] [Times: user=3.34 sys=0.05, real=0.15 secs] 
800.202: [GC 800.202: [ParNew: 559489K->246K(629120K), 0.1665870 secs] 95407015K->94847777K(158690816K), 0.1666610 secs] [Times: user=3.79 sys=0.00, real=0.17 secs] 
800.402: [GC 800.402: [ParNew: 559478K->257K(629120K), 0.1536610 secs] 95407009K->94847788K(158690816K), 0.1537290 secs] [Times: user=3.48 sys=0.02, real=0.15 secs]

年轻一代的大小为 629120K (=629M),我对此感到非常困惑,而我预计它大约为 629120K (=629M)。 Tenured Generation 大小的 1/2(因为 NewRatio=2),即 158690816K (=158G)。 Tenured 大小生成与预期的 NewRatio 和 Xms 相对应,即它是总堆大小的 2/3。

JVM 版本: java version "1.7.0_21" Java(TM) SE Runtime Environment (build 1.7.0_21-b11) Java HotSpot(TM) 64-Bit Server VM (build 23.21-b01, mixed mode)

更新: 我相信此时(800 秒的运行时间)程序的临时数组使用率达到峰值。 如果程序没有超过 629M Young generation size,是否意味着我应该增加 NewRatio?假设我打算给程序更多的工作量,并且我希望临时阵列体积与永久阵列体积的比例相同。

我之前用 NewRatio=8 运行程序,gc log 主要由如下几行组成:

800.004: [GC 800.004: [ParNew: 186594K->242K(209664K), 0.1059450 secs] 95345881K->95159529K(126655428K), 0.1060110 secs] [Times: user=2.41 sys=0.00, real=0.10 secs] 
800.122: [GC 800.122: [ParNew: 186610K->221K(209664K), 0.1073210 secs] 95345897K->95159522K(126655428K), 0.1073900 secs] [Times: user=2.37 sys=0.07, real=0.11 secs] 
800.240: [GC 800.240: [ParNew: 186589K->221K(209664K), 0.1026210 secs] 95345890K->95159524K(126655428K), 0.1026870 secs] [Times: user=2.34 sys=0.00, real=0.10 secs] 
800.357: [GC 800.357: [ParNew: 186589K->218K(209664K), 0.1043130 secs] 95345892K->95159527K(126655428K), 0.1043810 secs] [Times: user=2.30 sys=0.07, real=0.10 secs] 

这让我觉得 NewRatio 目前对年轻代大小有影响,但不应该因为目前年轻代远远低于堆大小的 1/9。

更新 2:这是一个巨大的科学计算,我的解决方案需要高达 240GB 的内存。这不是内存泄漏,算法是我能想到的最好的。

【问题讨论】:

  • 有什么问题?如果有需要,年轻代只会增加到 1/2*tenured。是什么让您认为它不会进一步扩展?
  • Jatin,我更新了问题,问题是在 NewRatio=8 的情况下,年轻一代在程序执行的同一点更小
  • CMS 不会动态扩展年轻的大小。更改堆几何结构需要在 STW 暂停中进行完全 GC。
  • 240g 是非常大的堆,我怀疑溢出发生在大小逻辑内部的某个地方。尝试在openjdk邮件列表hotspot-gc-use@openjdk.java.net上询问,这可能是一个错误。
  • Alexey Ragozin ,我更新了问题,我的程序可能需要高达 240g 的内存。

标签: garbage-collection jvm jvm-arguments


【解决方案1】:

请您尝试在禁用 AdaptiveSizePolicy 的情况下运行,使用:-XX-UseAdaptiveSizePolicy

这应该允许您预设每个堆区域的大小,并将在运行时禁用其大小的动态变化。

【讨论】:

    【解决方案2】:

    首先,检查What is the meaning of the -XX:NewRatio and -XX:OldSize JVM flags?

    NewRatio 是年轻代与老年代的比率(例如,值 2 表示 old 的最大大小将是 Young 的最大大小的两倍,即年轻可以达到堆的 1/3)。

    你会看到你的年轻代大小是正确的。

    我建议你也检查一下Are ratios between spaces/generations in the Java Heap constant? 并从一开始就使用设置静态大小

    -Xms240g -Xmx240g -XX:NewSize=120g -XX:MaxNewSize=120g -XX:-UseAdaptiveSizePolicy
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2011-04-17
      • 2023-02-24
      • 1970-01-01
      • 2014-07-24
      • 1970-01-01
      • 1970-01-01
      • 2023-02-09
      • 2011-08-28
      相关资源
      最近更新 更多