private static final int _1MB = 1024 * 1024;
public static void main(String[] args) {
testAllocation();
// testPretenureSizeThreshold();
}
/**
* -verbose:gc -Xms20M -Xmx20M -Xmn10M -XX:+PrintGCDetails -XX:SurvivorRatio=8
*/
public static void testAllocation() {
byte[] allocation1, allocation2, allocation3, allocation4;
allocation1 = new byte[2 * _1MB];
allocation2 = new byte[2 * _1MB];
allocation3 = new byte[2 * _1MB];
allocation4 = new byte[5 * _1MB];
}
/**
* -verbose:gc -Xms20M -Xmx20M -Xmn10M -XX:+PrintGCDetails -XX:SurvivorRatio=8 -XX:PretenureSizeThreshold=3145728
*/
public static void testPretenureSizeThreshold() {
byte[] allocation;
allocation = new byte[4 * _1MB];
}
1)在文章上是这样说的,testAllocation()在执行到allocation4 = new byte[5 * _1MB];的时候会超出新生代,导致产生一次minor GC,可是我在打印GC信息的过程中并没有发生GC,下面是我打印的结果:
Heap
PSYoungGen total 9216K, used 6979K [0x00000000ff600000, 0x0000000100000000, 0x0000000100000000)
eden space 8192K, 85% used [0x00000000ff600000,0x00000000ffcd0fa0,0x00000000ffe00000)
from space 1024K, 0% used [0x00000000fff00000,0x00000000fff00000,0x0000000100000000)
to space 1024K, 0% used [0x00000000ffe00000,0x00000000ffe00000,0x00000000fff00000)
ParOldGen total 10240K, used 5120K [0x00000000fec00000, 0x00000000ff600000, 0x00000000ff600000)
object space 10240K, 50% used [0x00000000fec00000,0x00000000ff100010,0x00000000ff600000)
PSPermGen total 21504K, used 2483K [0x00000000f9a00000, 0x00000000faf00000, 0x00000000fec00000)
object space 21504K, 11% used [0x00000000f9a00000,0x00000000f9c6cd80,0x00000000faf00000)
感觉allocation4 = new byte[5 * _1MB];直接进入了年老代,有点迷茫
2)执行testPretenureSizeThreshold方法的时候,我已经指定了XX:PretenureSizeThreshold=3145728,也就是说当我开创allocation = new byte[4 * _1MB]; 一个大于3MB的空间时候,应该直接进入年老代,但是打印结果却是:
Heap
PSYoungGen total 9216K, used 4931K [0x00000000ff600000, 0x0000000100000000, 0x0000000100000000)
eden space 8192K, 60% used [0x00000000ff600000,0x00000000ffad0f80,0x00000000ffe00000)
from space 1024K, 0% used [0x00000000fff00000,0x00000000fff00000,0x0000000100000000)
to space 1024K, 0% used [0x00000000ffe00000,0x00000000ffe00000,0x00000000fff00000)
ParOldGen total 10240K, used 0K [0x00000000fec00000, 0x00000000ff600000, 0x00000000ff600000)
object space 10240K, 0% used [0x00000000fec00000,0x00000000fec00000,0x00000000ff600000)
PSPermGen total 21504K, used 2483K [0x00000000f9a00000, 0x00000000faf00000, 0x00000000fec00000)
object space 21504K, 11% used [0x00000000f9a00000,0x00000000f9c6cd80,0x00000000faf00000)
从打印上看,并没有进入到年老代。
请大神指导,我用的JDK是1.7.0.51,eclipse下编译。
5 个解决方案
#1
你确定在Eclipse下正确设置了VM参数没有?我试了没问题啊,虽然我用的是JDK8下的1.7环境,但JDK7也不应该有问题啊
第一个测试
[GC (Allocation Failure) [DefNew: 6809K->464K(9216K), 0.0042200 secs] 6809K->6608K(19456K), 0.0042709 secs] [Times: user=0.00 sys=0.00, real=0.01 secs]
Heap
def new generation total 9216K, used 5912K [0x03a00000, 0x04400000, 0x04400000)
eden space 8192K, 66% used [0x03a00000, 0x03f520a0, 0x04200000)
from space 1024K, 45% used [0x04300000, 0x043741d8, 0x04400000)
to space 1024K, 0% used [0x04200000, 0x04200000, 0x04300000)
tenured generation total 10240K, used 6144K [0x04400000, 0x04e00000, 0x04e00000)
the space 10240K, 60% used [0x04400000, 0x04a00030, 0x04a00200, 0x04e00000)
Metaspace used 79K, capacity 2242K, committed 2368K, reserved 4480K
第二个测试
Heap
def new generation total 9216K, used 829K [0x03800000, 0x04200000, 0x04200000)
eden space 8192K, 10% used [0x03800000, 0x038cf5a8, 0x04000000)
from space 1024K, 0% used [0x04000000, 0x04000000, 0x04100000)
to space 1024K, 0% used [0x04100000, 0x04100000, 0x04200000)
tenured generation total 10240K, used 4096K [0x04200000, 0x04c00000, 0x04c00000)
the space 10240K, 40% used [0x04200000, 0x04600010, 0x04600200, 0x04c00000)
Metaspace used 79K, capacity 2242K, committed 2368K, reserved 4480K
第一个测试
[GC (Allocation Failure) [DefNew: 6809K->464K(9216K), 0.0042200 secs] 6809K->6608K(19456K), 0.0042709 secs] [Times: user=0.00 sys=0.00, real=0.01 secs]
Heap
def new generation total 9216K, used 5912K [0x03a00000, 0x04400000, 0x04400000)
eden space 8192K, 66% used [0x03a00000, 0x03f520a0, 0x04200000)
from space 1024K, 45% used [0x04300000, 0x043741d8, 0x04400000)
to space 1024K, 0% used [0x04200000, 0x04200000, 0x04300000)
tenured generation total 10240K, used 6144K [0x04400000, 0x04e00000, 0x04e00000)
the space 10240K, 60% used [0x04400000, 0x04a00030, 0x04a00200, 0x04e00000)
Metaspace used 79K, capacity 2242K, committed 2368K, reserved 4480K
第二个测试
Heap
def new generation total 9216K, used 829K [0x03800000, 0x04200000, 0x04200000)
eden space 8192K, 10% used [0x03800000, 0x038cf5a8, 0x04000000)
from space 1024K, 0% used [0x04000000, 0x04000000, 0x04100000)
to space 1024K, 0% used [0x04100000, 0x04100000, 0x04200000)
tenured generation total 10240K, used 4096K [0x04200000, 0x04c00000, 0x04c00000)
the space 10240K, 40% used [0x04200000, 0x04600010, 0x04600200, 0x04c00000)
Metaspace used 79K, capacity 2242K, committed 2368K, reserved 4480K
#2
你肯定把两个测试的参数弄反了。。我反过来试了一下和你的结果一样
#3
我确定没有将参数弄反,但是现在我可以得到正确答案了,但是我加上了-verbose:gc -Xms20M -Xmx20M -Xmn10M -XX:+PrintGCDetails -XX:SurvivorRatio=8 -XX:
+UseSerialGC
我想问下+UseSerialGC加上这个串行化就可以得到正确答案?那本身默认的是什么?我看还有2种是并行和并发,那默认的是哪一种,为什么其他的就得不到正确的结果呢
我想问下+UseSerialGC加上这个串行化就可以得到正确答案?那本身默认的是什么?我看还有2种是并行和并发,那默认的是哪一种,为什么其他的就得不到正确的结果呢
#4
原来不同机器默认GC还不同
我换了一台多核CPU的电脑发现和你一样,默认是Parallel Scavenge GC,而单核机器上默认是Serial GC
这个PS GC确实比较奇葩,Serial GC和ParNew GC都没问题,但PS GC好像无视PretenureSizeThreshold这个参数,而且当Eden区放不下的时候,是马上进行Minor GC还是直接放入Tenured区也不是确定的,要根据Eden区有多满以及新创建的数据有多大来决定
我翻了各种资料,中文英文搜索搜了半天,也没找到一篇讲PS GC具体工作机制的文章,几乎全是概念性的泛泛而谈毫无价值,所以也不太清楚PS GC到底是什么策略
我换了一台多核CPU的电脑发现和你一样,默认是Parallel Scavenge GC,而单核机器上默认是Serial GC
这个PS GC确实比较奇葩,Serial GC和ParNew GC都没问题,但PS GC好像无视PretenureSizeThreshold这个参数,而且当Eden区放不下的时候,是马上进行Minor GC还是直接放入Tenured区也不是确定的,要根据Eden区有多满以及新创建的数据有多大来决定
我翻了各种资料,中文英文搜索搜了半天,也没找到一篇讲PS GC具体工作机制的文章,几乎全是概念性的泛泛而谈毫无价值,所以也不太清楚PS GC到底是什么策略
#5
看来还是得多看下资料,虽然还是不明白,但是非常感谢你了。这一块的东西有的好恶补了,不是一个帖子能解决的。十分感谢。
#1
你确定在Eclipse下正确设置了VM参数没有?我试了没问题啊,虽然我用的是JDK8下的1.7环境,但JDK7也不应该有问题啊
第一个测试
[GC (Allocation Failure) [DefNew: 6809K->464K(9216K), 0.0042200 secs] 6809K->6608K(19456K), 0.0042709 secs] [Times: user=0.00 sys=0.00, real=0.01 secs]
Heap
def new generation total 9216K, used 5912K [0x03a00000, 0x04400000, 0x04400000)
eden space 8192K, 66% used [0x03a00000, 0x03f520a0, 0x04200000)
from space 1024K, 45% used [0x04300000, 0x043741d8, 0x04400000)
to space 1024K, 0% used [0x04200000, 0x04200000, 0x04300000)
tenured generation total 10240K, used 6144K [0x04400000, 0x04e00000, 0x04e00000)
the space 10240K, 60% used [0x04400000, 0x04a00030, 0x04a00200, 0x04e00000)
Metaspace used 79K, capacity 2242K, committed 2368K, reserved 4480K
第二个测试
Heap
def new generation total 9216K, used 829K [0x03800000, 0x04200000, 0x04200000)
eden space 8192K, 10% used [0x03800000, 0x038cf5a8, 0x04000000)
from space 1024K, 0% used [0x04000000, 0x04000000, 0x04100000)
to space 1024K, 0% used [0x04100000, 0x04100000, 0x04200000)
tenured generation total 10240K, used 4096K [0x04200000, 0x04c00000, 0x04c00000)
the space 10240K, 40% used [0x04200000, 0x04600010, 0x04600200, 0x04c00000)
Metaspace used 79K, capacity 2242K, committed 2368K, reserved 4480K
第一个测试
[GC (Allocation Failure) [DefNew: 6809K->464K(9216K), 0.0042200 secs] 6809K->6608K(19456K), 0.0042709 secs] [Times: user=0.00 sys=0.00, real=0.01 secs]
Heap
def new generation total 9216K, used 5912K [0x03a00000, 0x04400000, 0x04400000)
eden space 8192K, 66% used [0x03a00000, 0x03f520a0, 0x04200000)
from space 1024K, 45% used [0x04300000, 0x043741d8, 0x04400000)
to space 1024K, 0% used [0x04200000, 0x04200000, 0x04300000)
tenured generation total 10240K, used 6144K [0x04400000, 0x04e00000, 0x04e00000)
the space 10240K, 60% used [0x04400000, 0x04a00030, 0x04a00200, 0x04e00000)
Metaspace used 79K, capacity 2242K, committed 2368K, reserved 4480K
第二个测试
Heap
def new generation total 9216K, used 829K [0x03800000, 0x04200000, 0x04200000)
eden space 8192K, 10% used [0x03800000, 0x038cf5a8, 0x04000000)
from space 1024K, 0% used [0x04000000, 0x04000000, 0x04100000)
to space 1024K, 0% used [0x04100000, 0x04100000, 0x04200000)
tenured generation total 10240K, used 4096K [0x04200000, 0x04c00000, 0x04c00000)
the space 10240K, 40% used [0x04200000, 0x04600010, 0x04600200, 0x04c00000)
Metaspace used 79K, capacity 2242K, committed 2368K, reserved 4480K
#2
你肯定把两个测试的参数弄反了。。我反过来试了一下和你的结果一样
#3
我确定没有将参数弄反,但是现在我可以得到正确答案了,但是我加上了-verbose:gc -Xms20M -Xmx20M -Xmn10M -XX:+PrintGCDetails -XX:SurvivorRatio=8 -XX:
+UseSerialGC
我想问下+UseSerialGC加上这个串行化就可以得到正确答案?那本身默认的是什么?我看还有2种是并行和并发,那默认的是哪一种,为什么其他的就得不到正确的结果呢
我想问下+UseSerialGC加上这个串行化就可以得到正确答案?那本身默认的是什么?我看还有2种是并行和并发,那默认的是哪一种,为什么其他的就得不到正确的结果呢
#4
原来不同机器默认GC还不同
我换了一台多核CPU的电脑发现和你一样,默认是Parallel Scavenge GC,而单核机器上默认是Serial GC
这个PS GC确实比较奇葩,Serial GC和ParNew GC都没问题,但PS GC好像无视PretenureSizeThreshold这个参数,而且当Eden区放不下的时候,是马上进行Minor GC还是直接放入Tenured区也不是确定的,要根据Eden区有多满以及新创建的数据有多大来决定
我翻了各种资料,中文英文搜索搜了半天,也没找到一篇讲PS GC具体工作机制的文章,几乎全是概念性的泛泛而谈毫无价值,所以也不太清楚PS GC到底是什么策略
我换了一台多核CPU的电脑发现和你一样,默认是Parallel Scavenge GC,而单核机器上默认是Serial GC
这个PS GC确实比较奇葩,Serial GC和ParNew GC都没问题,但PS GC好像无视PretenureSizeThreshold这个参数,而且当Eden区放不下的时候,是马上进行Minor GC还是直接放入Tenured区也不是确定的,要根据Eden区有多满以及新创建的数据有多大来决定
我翻了各种资料,中文英文搜索搜了半天,也没找到一篇讲PS GC具体工作机制的文章,几乎全是概念性的泛泛而谈毫无价值,所以也不太清楚PS GC到底是什么策略
#5
看来还是得多看下资料,虽然还是不明白,但是非常感谢你了。这一块的东西有的好恶补了,不是一个帖子能解决的。十分感谢。