性能问答>JVM 不同GC回收器的表现差别这么大?>
3回复
2年前

JVM 不同GC回收器的表现差别这么大?



想测试相同代码在不同的垃圾回收器下面的不同表现,所以写了一段代码:

public static void main(String[] args) {
    long start = System.currentTimeMillis();
    byte[] firstAlloc = new byte[_1M * 4];
    System.out.println("first allocation");

    byte[] secondAlloc = new byte[_1M * 4];
    System.out.println("second allocation");

    byte[] thirdAlloc = new byte[_1M * 2];
    System.out.println("third allocation");

    byte[] fourthdAlloc = new byte[_1M * 4];
    System.out.println("fourth allocation");

    System.out.println("cost: " + (System.currentTimeMillis() - start));
}

非常简单的代码就是总共分配14M的byte数组,分别2使用2次不同的GC回收器,使用的是jdk1.8 两次的VM参数是和结果分别:

第一次:

-verbose:gc -Xmx20M -Xms20M -Xmn10M -XX:+PrintGCDetails -XX:SurvivorRatio=8

image.png

第二次:

-verbose:gc -Xmx20M -Xms20M -Xmn10M -XX:+PrintGCDetails -XX:SurvivorRatio=8 -XX:+UseConcMarkSweepGC

image.png

有几个困惑的点

  1. jdk默认是使用Parallel Scanvage + Parallel Old来进行垃圾回收,代码中前3次分配我理解应该会有GC出现,但是实际从结果看4次分配都未出现GC分配失败的日志

  2. 第二次使用ParNew + CMS来进行回收,从结果看第二次分配的时候就触发了Minor GC,但是Eden区按道理应该有8M空间理应可以分配下的,另外从表现看相同代码CMS比1.8默认的表现差了1倍(cost是20ms), 困惑二是为什么会有这么大的性能差距,如果CMS这么差那设计这个垃圾回收器的意义何在?

3153 阅读
请先登录,再评论

对于第二个问题没有可比性,CMS GC并不是因为你这个demo而表现性能差,既然做了GC,肯定会影响耗时

2年前

PS下先在新生代分配4M,再在老生代分配4M,再在新生代分配2M,再在老生代分配4M,此时不会发生GC

2年前

1.换个高版本的jdk就能看到allocation failure
2.因为Eden里面有其它对象,你调大点mn第二次就不会失败了

2年前