【发布时间】: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