JVM学习笔记_垃圾收集器重要参数

垃圾收集器有串行收集器,比如 Serial收集器+Serial Old收集器,Parallel Scavenge+Parallel Old收集器等等。该如何让这些不同的垃圾收集器组合触发使用呢?

-XX:+UseParallelGC

在1.8版本的JDK运行时,JVM默认采用此种垃圾收集器组合来进行垃圾回收。可以通过+PrintCommandLineFlags参数查看JVM运行默认设置的JVM参数信息。

JVM设置-XX:+UseParallelGC参数,即采用此种垃圾收集器进行垃圾回收。在JDK 1.8.0_291版本默认使用此种收集策略。

收集器垃圾回收日志格式如下:

在这里插入图片描述

其中,PSYongGenParOldGen就印证了使用Parallel Scavenge+Parallel Old收集器进行垃圾回收。

-XX:+UseSerialGC

设置该参数后,JVM使用Serial+Serial Old收集器进行垃圾回收,DefNew和Tenured分别与之对应。

在这里插入图片描述

-XX:+UseParNewGC

设置该参数后, JVM使用ParNew+Serial Old收集器进行垃圾回收。

在这里插入图片描述

JVM有明确提示,不建议这么设置:

Java HotSpot(TM) 64-Bit Server VM warning: Using the ParNew young collector with the Serial old collector is deprecated and will likely be removed in a future release
-XX:+UseConcMarkSweepGC

​ 老年代使用CMS收集器。

-XX:PretenureSizeThreshold

-XX:PretenureSizeThreshold 设置对象超过多大值时直接在老年代分配。需要显示指定垃圾回收器类型,否则不会生效。

示例配置:

-verbose:gc
-Xmn10M
-Xms20M
-Xmx20M
-XX:+PrintGCDetails
-XX:SurvivorRatio=8
-XX:PretenureSizeThreshold=4194304
-XX:+UseSerialGC
-XX:MaxTenuringThreshold

该参数主要是控制新生代需要经历多少次GC晋升到老年代中的最大阈值。

该参数默认值15,CMS默认值6,G1默认值15(在JVM中,该数值由4个bit表示,最大值为1111,即15)

但并非意味着,对象必须要经历15次YGC才会晋升到老年代中。例如,当survivor区空间不够时,便会提前进入到老年代中,但这个次数一定不大于设置的最大阈值。

-XX:TargetSurvivorRatio

一个计算期望s区存活大小(Desired survivor size)的参数。默认值为50,即50%。
当一个S区中所有的age对象的大小如果大于等于Desired survivor size,则重新计算threshold,以age和MaxTenuringThreshold两者的最小值为准, 即

newThreshold = min(age, MaxTenuringThreshold);

如下代码能更好地理解MaxTenuringThreshold与TargetSurvivorRatio这两个参数:

/**
 * #### -XX:MaxTenuringThreshold
 * <p>
 * 在可以自动调节对象晋升到老年代阈值的GC中,设置该阈值的最大值。
 * <p>
 * 该参数默认值15,CMS默认值6,G1默认值15(在JVM中,该数值由4个bit表示,最大值为1111,即15)
 * <p>
 * 晋升到老年代的对象的年龄。每个对象在坚持过一次Minor GC后,年龄就+1。
 *
 *
 * 当一个S区中所有的age对象的大小如果大于等于Desired survivor size
 * 则重新计算threshold,以age和MaxTenuringThreshold两者的最小值为准
 */

/*
-verbose:gc
-Xmx200m  //最大堆空间大小为200M
-Xmn50m   //新生代大小50M
-XX:TargetSurvivorRatio=60 //当Survivor空间已使用60%,则重新计算对象晋升的阈值, 不会在使用MaxTenuringThreshold的值
-XX:+PrintTenuringDistribution // 打印对象在survivor空间的年龄情况,有多少对象的age是多少
-XX:+PrintGCDetails
-XX:SurvivorRatio=8
-XX:MaxTenuringThreshold=4 //对象在新生代存活年龄的最大值的阈值
-XX:+PrintGCDateStamps  //打印gc的时间戳
-XX:+UseParNewGC  // 针对新生代的垃圾收集器
-XX:+UseConcMarkSweepGC  //针对老年代,使用CMS收集器
 */
public class MyTest3 {

    public static void main(String[] args) throws InterruptedException {
      
        // 新生代大小50M,Eden40M,Survivor区5M

        // 总共1M,在该方法执行完之前,不会被回收
        byte[] byte_1 = new byte[512 * 1024];
        byte[] byte_2 = new byte[512 * 1024];

        // 执行后,存在对象分配和垃圾回收,byte_1+byte_2会进S0,age=1
        myGC();
        Thread.sleep(1000);
        System.out.println("111111=========================================");

        //执行后,byte_1+byte_2会进S1,age=2
        myGC();
        Thread.sleep(1000);
        System.out.println("222222=========================================");

        // 执行后,byte_1+byte_2会进S0,age=3
        myGC();
        Thread.sleep(1000);
        System.out.println("3333333=========================================");

        // 执行后,byte_1+byte_2会进S1,age=4
        myGC();
        Thread.sleep(1000);
        System.out.println("444444444=========================================");

        //因为已经达到MaxTenuringThreshold=4阈值,因此之前age=4的对象会被晋升到老年代
        //可以看到新生代垃圾回收后的空间有明显的下降
        myGC();
        Thread.sleep(1000);
        System.out.println("555555555=========================================");


        // byte_3+byte_4+byte_5为3M ,注意,byte_1和byte_2已经在老年代了
        byte[] byte_3 = new byte[1024 * 1024];
        byte[] byte_4 = new byte[1024 * 1024];
        byte[] byte_5 = new byte[1024 * 1024];

        //S区所有age的对象大小超过60%阈值,达到TargetSurvivorRatio=60, 重置new threshold=1
        myGC();
        Thread.sleep(1000);
        System.out.println("66666666666=========================================");

        byte[] byte_6 = new byte[1024 * 1024]; //这个对象在下次GC时会在S区,不会进入老年代
      
       //虽然未达到MaxTenuringThreshold=4,但是已经满足TargetSurvivorRatio=60,S区之前的age1、age2、age3、age4的对象都进入老年代,重置new threshold=4; 这里区别byte_6的内存情况
        myGC();
        System.out.println("7777777777=========================================");
    }

    /**
     * 产生40M大小,From会被占满,会触发垃圾回收
     */
    private static void myGC() {

        for (int i = 0; i < 40; i++) {
            // 1M
            byte[] myarr = new byte[1024 * 1024];
        }
    }
}

使用的VM参数如下:

-verbose:gc
-Xmx200m
-Xmn50m
-XX:+PrintGCDetails
-XX:SurvivorRatio=8
-XX:MaxTenuringThreshold=4
-XX:+PrintGCDateStamps
-XX:+UseParNewGC
-XX:+UseConcMarkSweepGC
-XX:TargetSurvivorRatio=60
-XX:+PrintTenuringDistribution

运行结果可通过程序直接得出,一些细节参考代码注释。

2022-02-21T01:08:02.388-0800: [GC (Allocation Failure) 2022-02-21T01:08:02.388-0800: [ParNew
Desired survivor size 3145728 bytes, new threshold 4 (max 4)
- age   1:    1471672 bytes,    1471672 total
: 40141K->1480K(46080K), 0.0009180 secs] 40141K->1480K(199680K), 0.0009636 secs] [Times: user=0.00 sys=0.00, real=0.00 secs] 
111111=========================================
2022-02-21T01:08:03.392-0800: [GC (Allocation Failure) 2022-02-21T01:08:03.392-0800: [ParNew
Desired survivor size 3145728 bytes, new threshold 4 (max 4)
- age   1:       1744 bytes,       1744 total
- age   2:    1460000 bytes,    1461744 total
: 42006K->1571K(46080K), 0.0010912 secs] 42006K->1571K(199680K), 0.0011157 secs] [Times: user=0.00 sys=0.00, real=0.00 secs] 
222222=========================================
2022-02-21T01:08:04.398-0800: [GC (Allocation Failure) 2022-02-21T01:08:04.398-0800: [ParNew
Desired survivor size 3145728 bytes, new threshold 4 (max 4)
- age   1:     345896 bytes,     345896 total
- age   2:       1744 bytes,     347640 total
- age   3:    1459864 bytes,    1807504 total
: 41692K->2018K(46080K), 0.0012447 secs] 41692K->2018K(199680K), 0.0012923 secs] [Times: user=0.01 sys=0.00, real=0.01 secs] 
3333333=========================================
2022-02-21T01:08:05.409-0800: [GC (Allocation Failure) 2022-02-21T01:08:05.409-0800: [ParNew
Desired survivor size 3145728 bytes, new threshold 4 (max 4)
- age   1:        136 bytes,        136 total
- age   2:     345272 bytes,     345408 total
- age   3:       1744 bytes,     347152 total
- age   4:    1459560 bytes,    1806712 total
: 42730K->2094K(46080K), 0.0012483 secs] 42730K->2094K(199680K), 0.0012961 secs] [Times: user=0.00 sys=0.00, real=0.01 secs] 
444444444=========================================
2022-02-21T01:08:06.418-0800: [GC (Allocation Failure) 2022-02-21T01:08:06.418-0800: [ParNew
Desired survivor size 3145728 bytes, new threshold 4 (max 4)
- age   1:        144 bytes,        144 total
- age   2:        136 bytes,        280 total
- age   3:     345216 bytes,     345496 total
- age   4:       1744 bytes,     347240 total
: 42815K->780K(46080K), 0.0042800 secs] 42815K->2248K(199680K), 0.0043233 secs] [Times: user=0.01 sys=0.01, real=0.01 secs] 
555555555=========================================
2022-02-21T01:08:07.430-0800: [GC (Allocation Failure) 2022-02-21T01:08:07.430-0800: [ParNew
Desired survivor size 3145728 bytes, new threshold 1 (max 4)
- age   1:    3145920 bytes,    3145920 total
- age   2:        144 bytes,    3146064 total
- age   3:        136 bytes,    3146200 total
- age   4:     345416 bytes,    3491616 total
: 41508K->3491K(46080K), 0.0021719 secs] 42976K->4961K(199680K), 0.0022176 secs] [Times: user=0.01 sys=0.00, real=0.00 secs] 
66666666666=========================================
2022-02-21T01:08:08.440-0800: [GC (Allocation Failure) 2022-02-21T01:08:08.440-0800: [ParNew
Desired survivor size 3145728 bytes, new threshold 4 (max 4)
- age   1:    1048736 bytes,    1048736 total
: 44223K->1063K(46080K), 0.0044809 secs] 45693K->5949K(199680K), 0.0045236 secs] [Times: user=0.02 sys=0.00, real=0.00 secs] 
7777777777=========================================
Heap
 par new generation   total 46080K, used 22137K [0x00000007b3800000, 0x00000007b6a00000, 0x00000007b6a00000)
  eden space 40960K,  51% used [0x00000007b3800000, 0x00000007b4c94870, 0x00000007b6000000)
  from space 5120K,  20% used [0x00000007b6500000, 0x00000007b6609ef0, 0x00000007b6a00000)
  to   space 5120K,   0% used [0x00000007b6000000, 0x00000007b6000000, 0x00000007b6500000)
 concurrent mark-sweep generation total 153600K, used 4886K [0x00000007b6a00000, 0x00000007c0000000, 0x00000007c0000000)
 Metaspace       used 3704K, capacity 4536K, committed 4864K, reserved 1056768K
  class space    used 415K, capacity 428K, committed 512K, reserved 1048576K

Process finished with exit code 0

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值