较小的伊甸园空间会导致土地使用空间不断增加吗?

时间:2012-04-11 17:34:15

标签: java memory-management jvm

我将首先介绍我们创建的对象的一些细节。并会问一个问题(最后)。

我在linux上使用64但是JVM。

我的jvm选项是:-Xmx6g -Xms3g -XX:MaxPermSize = 256m

探查器(jprofiler)表示占用大量内存的2个位置: 1)这里,每秒创建大约4个字符串(每个110KB),并对每个字符串执行StringUtils.replace。还会执行一些其他字符串分配等,但是分析器清楚地表明StringUtils.replace是占用大部分内存的东西。 2)这里,每分钟创建一个包含4个对象(单个类)的对象(保留大小,如果为3.5MB),并且(重新)放入静态并发哈希图(因此,地图在任何时候只包含1个对象)。所有父对象都有这4个子对象而没有别的。这4个对象中的每一个都包含10K arraylists,10K Date和其他字符串等。我明确地将旧的父对象(我从map.replace()得到的对象)分配给null并显式清除(ArrayList.clear())这4个子对象中的ArrayList等。

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

问题:您认为#1实际上是否导致eden空间已满,因此JVM正在将#2中的对象推送到任期空间,因此内存使用量会持续增加,直到发生重大收集?出于诊断目的,我将#2中的父对象更改为保留大小为500KB(7倍小,还有1.4K实例的Date,ArrayList等),我仍然看到相同的内存行为。

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

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

有关我应采取何种方法的任何建议?

1 个答案:

答案 0 :(得分:3)

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

当你每两分钟创建大约6 GB的对象时(NewSize包含两个幸存者空间),或者每分钟大约3 GB,其中大部分是来自你建议的大小每分钟只有几MB

我认为更好地了解3 GB的来源并减少它会很有用,因为看起来你只需要保持每分钟大约10 MB。

BTW:如果你每分钟要创造10 MB的垃圾,你只需要在10个小时内创建6 GB的垃圾,那时你就不需要任何小型或大型的垃圾。

如果我跑

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时间。它保留的对象数量增加,这增加了所需的时间。