尽管NewRatio = 2,但年轻一代很小

时间:2013-04-21 09:57:35

标签: garbage-collection jvm jvm-arguments

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

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]

我对Young Generation尺寸为629120K(= 629M)这一事实感到非常困惑,而我认为它是大约。 Tenured Generation大小的1/2(因为NewRatio = 2)是158690816K(= 158G)。终身尺寸生成与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年轻一代,是否意味着我应该增加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的内存。这不是内存泄漏,算法是我能想到的最好的算法。

2 个答案:

答案 0 :(得分:1)

请问,您是否可以尝试禁用AdaptiveSizePolicy,请使用:-XX-UseAdaptiveSizePolicy

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

答案 1 :(得分:0)

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

  

NewRatio是年轻一代与老一代的比例(例如,值2意味着最大尺寸将是年轻人的最大尺寸的两倍,即年轻人可以达到堆的1/3)。

你会发现你的年轻一代是正确的。

我建议您同时检查Are ratios between spaces/generations in the Java Heap constant?并使用

从一开始就设置静态大小
-Xms240g -Xmx240g -XX:NewSize=120g -XX:MaxNewSize=120g -XX:-UseAdaptiveSizePolicy