2012-04-11 45 views
3

我将首先介绍我们创建的对象的一些细节。并会问一个问题(最终)。更小的伊甸园空间造成任期空间不断增加?

我在linux上使用64-JVM。

我的JVM选项有:-Xmx6g -Xms3g -XX:MaxPermSize参数=256米

探查(JProfiler的)表示2个地方消耗大量的内存:每秒 1)在此,约4字符串(每个110KB)被创建并且StringUtils.replace在每个字符串上执行。一些其他的字符串分配等也被执行,但分析器清楚地表明StringUtils.replace是持有大部分内存的东西。 2)在这里,每分钟创建一个包含4个对象(一个类的对象)的对象(保留大小为3.5MB),并(重新)放入一个静态的同步映射(因此映射只包含1个对象)。所有的父对象都有这4个子对象,没有别的。这4个对象中的每一个都包含10K数组列表,10K日期和其他字符串等。我明确指定旧的父对象(我从map.replace()获得的那个对象)为null并显式清除(ArrayList.clear())out这4个子对象内的ArrayList等。

内存行为是:内存使用量不断增加,并在一个主要集合(2GB)发生。次要收集(700MB)也每分钟发生一次。

问题:你认为#1实际上是导致eden空间满了,所以JVM会将#2中的对象推到任务空间,所以内存使用量不断增加,直到发生重大聚集?出于诊断目的,我将#2中的父对象更改为保留大小为500KB(较小7次,还有Date,ArrayList等的1.4K实例),并且我仍然看到相同的内存行为。

我将选项更改为-Xmx12g -Xms3g -XX:MaxPermSize = 256m -XX:NewSize = 8g现在,我在内存#2中看到较少的对象#我看到使用空间/旧创建的增长较慢。它的好处在于#2中的这些对象正在被快速收集,但CPU使用率非常高,因为现在很小的收集量(8G)并且每2分钟发生一次。

我的目标是快速收集所有对象(所以我没有看到内存使用量不断增加),但不会使次要收集过大。

我应该采取什么方法的任何建议?

回答

2

收集伊甸园空间的成本与保留的伊甸园空间中的物品数量成正比。由于成本高昂,这表明大部分物品保留时间超过2分钟。

由于您每两分钟创建大约6GB的对象(NewSize包含两个生存空间),或者每分钟大约3GB,其中大部分来自此,因为您建议的大小只有几MB分钟。

我认为一个更好的3 GB来自哪里并且减少它会很有用,因为看起来你只需要保持每分钟大约10 MB。

顺便说一句:如果你每分钟创建10MB的垃圾,你只能在10个小时内创建6GB,那时你不需要任何次要或者主要的收集。

如果我运行

public class GCLikeMad { 
    public static void main(String... args) { 
     for(Long l = 0L; l < Integer.MAX_VALUE * 10L; l++); 
    } 
} 

-XX:NewSize=256m我看到

[GC 295664K->240K(2121792K), 0.0011190 secs] 
[GC 286832K->240K(2113216K), 0.0011510 secs] 
[GC 278384K->240K(2105216K), 0.0012900 secs] 
[GC 270256K->240K(2097280K), 0.0010110 secs] 
[GC 262448K->240K(2257280K), 0.0013450 secs] 

-XX:newSize=8g -verbosegc我看到

[GC 6291664K->320K(7345408K), 0.0017790 secs] 
[GC 6291776K->272K(7345408K), 0.0021570 secs] 
[GC 6291728K->272K(7345408K), 0.0014490 secs] 
[GC 6291728K->240K(8393600K), 0.0016680 secs] 
[GC 8388080K->208K(8393600K), 0.0018730 secs] 

-XX:NewSize=30g -mx31g -XX:SurvivorRatio=100 -verbosegc此时使用32位引用,并且只使用一个NUMA内存区域。

[GC 30840864K->256K(31154304K), 0.0014270 secs] 
[GC 30840832K->256K(31154304K), 0.0014730 secs] 
[GC 30840832K->224K(31154304K), 0.0016500 secs] 
[GC 30840800K->272K(31154304K), 0.0015740 secs] 
[GC 30840848K->272K(31462336K), 0.0015280 secs] 

-XX:NewSize=128g -mx130g -XX:SurvivorRatio=100 -verbosegc它开始有所作为。注意:此时正在使用多个NUMA内存区域和64位引用。这是每2分钟收集一次。

[GC 131586048K->320K(132907264K), 0.0042360 secs] 
[GC 131586368K->1376K(132907264K), 0.0058030 secs] 
[GC 131587424K->1440K(132907264K), 0.0034110 secs] 

在这一点上,它已经创建了200亿个只有三个集合的Long对象。

我会说一个128 GB的伊甸园空间是巨大的。 :D


我的观点是,增加伊甸园的大小,并不会增加GC时间本身。它增加了保留的对象数量,增加了所需的时间。

相关问题