GC垃圾收集器和内存分配

JVM默认老年代回收是 PSMarkSweep(Serial-Old) 还是Parallel Old? - 知乎

-XX:+UseG1GC -XX:+PrintGCTimeStamps -XX:+PrintGCApplicationStoppedTime -XX:+PrintGCDetails -Xloggc:gc.log -Dfile.encoding=gbk 

java -jar -XX:+UseG1GC -XX:+PrintGCTimeStamps -XX:+PrintGCDateStamps  -XX:+PrintGCApplicationStoppedTime -XX:+PrintGCDetails -Xloggc:gc.log springbootDemo12_0.jar 

2023-05-11T14:06:48.090+0800: 9.205: Total time for which application threads were stopped: 0.0001890 seconds, Stopping threads took: 0.0001305 seconds
2023-05-11T14:06:48.090+0800: 9.205: Total time for which application threads were stopped: 0.0001991 seconds, Stopping threads took: 0.0001356 seconds
2023-05-11T14:06:48.100+0800: 9.215: [GC concurrent-root-region-scan-end, 0.0232713 secs]
2023-05-11T14:06:48.100+0800: 9.215: [GC concurrent-mark-start]
2023-05-11T14:06:48.107+0800: 9.221: [GC concurrent-mark-end, 0.0065505 secs]
2023-05-11T14:06:48.107+0800: 9.222: [GC remark 2023-05-11T14:06:48.107+0800: 9.222: [Finalize Marking, 0.0084455 secs] 2023-05-11T14:06:48.116+0800: 9.231: [GC ref-proc, 0.0025846 secs] 2023-05-11T14:06:48.118+0800: 9.233: [Unloading, 0.0143943 secs], 0.0348725 secs]
 [Times: user=1.98 sys=0.06, real=0.04 secs] 
2023-05-11T14:06:48.142+0800: 9.257: Total time for which application threads were stopped: 0.0354685 seconds, Stopping threads took: 0.0001558 seconds
2023-05-11T14:06:48.143+0800: 9.257: [GC cleanup 30M->30M(2048M), 0.0261924 secs]
 [Times: user=0.27 sys=0.02, real=0.03 secs] 

-XX:+PrintGCTimeStamps:(虚拟机启动以来的时间),如2.639、3.280等

2.639: Total time for which application threads were stopped: 0.0006871 seconds, Stopping threads took: 0.0003649 seconds
3.280: Total time for which application threads were stopped: 0.0007132 seconds, Stopping threads took: 0.0001169 seconds
3.318: Total time for which application threads were stopped: 0.0007101 seconds, Stopping threads took: 0.0001088 seconds

-XX:+PrintGCDateStamps(详细时间戳)

在这里插入图片描述

-XX:+PrintGCDetails(打印详细信息,新生代和老年代包括元空间都有(jdk1.8))

-verbose:gc (或者-XX:+PrintGC)注意:不要有任何空格

G1作为JDK9+的默认GC.

JDK 1.8 默认使用 UseParallelGC 垃圾回收器,即 UseParallelGC is "Parallel Scavenge" + "Serial Old"

新生代(Parallel Scavenge),老年代(Ps MarkSweep)组合。

  • UseParallelGC is "Parallel Scavenge" + "Serial Old"
  • UseParallelOldGC is "Parallel Scavenge" + "Parallel Old"

64bit默认启动-server,-server下默认是PS回收框架组合,而PS回收框架下的两个参数,-XX:+UseParallelGC和-XX:+UseParallelOldGC默认都是指向并行收集器的,这是不是就说明,在默认情况前jvm启动的老年代收集器,就是ParallelOld??

以下是R大 RednaxelaFX 答案的节选,请移步答案区,非常感谢R大的解释。

“在这个改变之前,即便选择了ParallelGC,默认情况下ParallelOldGC并不会随即开启,而是要自己通过 -XX:+UseParallelOldGC 去选定。

在GC日志里,如果看到Full GC里有"ParOldGen"就是选择了ParallelOldGC。“

在这个改变之前,即便选择了ParallelGC,默认情况下ParallelOldGC并不会随即开启,而是要自己通过 -XX:+UseParallelOldGC 去选定。在GC日志里,如果看到Full GC里有"ParOldGen"就是选择了ParallelOldGC。

 

1、64bit的机器默认是-server生效的,且会忽略-client参数。

在虚拟机参数中添加 -XX:+PrintGCDetails  -XX:+PrintCommandLineFlags参数,可以查看,默认的新生代垃圾收集器是ParallelGC,老年代的收集器ParOldGen.

-XX:+UseSerialGC参数可以指定使用新生代串行收集器和老年代串行收集器。

在Client模式下运行时,默认是串行收集器。

新生代串行收集器是使用复制算法;老年代串行处理器使用标记压缩算法。

-XX:+UseSerialGC:新生代、老年代都使用串行处理器。

-XX:+UseParNewGC:新生代使用ParNew回收器,老年代使用串行处理器。

-XX:+UseParallelGC:新生代使用ParallelGC回收器,老年代使用串行处理器。

-XX:+UseParallelGC 新生代使用ParallelGC回收器,老年代使用串行处理器

-XX:+UseParallelOldGC 新生代使用ParallelGC回收器,老年代使用ParallelOldGC回收器。

-XX:+UseConcMarkSweepGC启用CMS回收器

实例:

1新生代串行收集器:

0.834[GC 0.834:[DefNew:1111k->xxxxxxxxx] ]

2 新生代ParNew处理器

0.834[GC 0.834:[ParNew:1111k->xxxxxxxxx] ]

3、老年代串行

0.834[Full GC 0.834:[Tenured:1111k->xxxxxxxxx] ]

4、新生代ParallelGC

0.880:[GC [PSYoungGen:16448k->xxxx]]

5、老年代ParallelOldGC回收器

1.500:[Full GC[PSYoungGen:2533k->xxxxxxxxxxxxxxxx]]

6、老年代CMS

1.313 :[GC [1 CMS-initial-mark:69112k    ]]

一、新生代ParNew回收器

ParNew使用

ParNew回收器是一个新生代工作的回收器,

-XX:+UseParNewGC:新生代使用ParNew回收器,老年代使用串行处理器。

-XX:+UseConcMarkSweepGC:新生代使用ParNew回收器,老年代使用CMS。

ParNew回收器工作时的线程数量可以使用-XX:ParallelGCThreads参数指定,一般线程数为cpu数。默认情况下,cpu<8时,ParallelGCThreads的值为cpu数量,如果大于8,值为3+((5*CPU_Count)/8),ParNew回收器日志为:

0.834[GC 0.834:[ParNew:1111k->xxxxxxxxx] ]

二、新生代ParallelGC回收器

新生代ParallelGC回收器也适用复制算法收集器,都是多线程、独占式的收集器,但它非常关注系统的吞吐量。

-XX:+UseParallelGC 新生代使用ParallelGC回收器,老年代使用串行处理器

ParallelGC回收器提供了两个重要的参数用于控制系统的吞吐量。

-XX:MaxGCPauseMillis:设置最大垃圾收集停顿时间,它的值是一个大于0的整数,会调整java堆大小伙子其他一些参数,尽可能把停顿时间控制在MaxGCPauseMillis以内。如设置该值很小,则虚拟机会使用一个较小的堆,便于垃圾回收,使回收时间短,但会带来垃圾回收频繁的问题,增加了垃圾回收总时间,降低了吞吐量。

-XX:GCTimeRatio:设置吞吐量大小。值在0~100之间的整数,如值为n,则会花费1/(1+n)的时间用于垃圾收集。如果把此参数设置为19,那允许的最大GC时间就占总时间的5%(即1/(1+19)),默认值为99,就是允许最大1%(即1/(1+99))的垃圾收集时间。

ParalletGC支持自适应,即设置

-XX:+UseAdaptiveSizePolicy可以打开自适应GC策略,每次都会重新计算新生代大小, Eden、survivor的比例,晋升老年代的对象年龄等参数都会被自动调整。以达到堆大小,吞吐量和停顿时间的平衡。在手工调优比较困难,可以直接指定这种自适应的方式,仅需指定堆的最大值,目标吞吐量(GCTimeRatio)和停顿时间(MaxGCPPauseMills),让虚拟机完成调优工作。

0.880:[GC [PSYoungGen:16448k->xxxx]]

JDK 1.8 默认使用 UseParallelGC 垃圾回收器,该垃圾回收器默认启动了 AdaptiveSizePolicy。

三、老年代ParallelOldGC回收器

老年代ParallelOldGC回收器也是一种多线程并发的收集器,和新生代ParallelGC回收器一样,也很关注系统吞吐量的收集器。

它从JDK1.6中才可以使用。

参数-XX:ParallelGCThreads也可以设置垃圾回收时的线程数量。

三、CMS回收器

CMS回收器主要关注于系统的停顿时间,是Concurrent Mark Sweep的缩写,意为并发标记清除,使用标记清除算法,同时也是一个使用多线程并行回收的垃圾收集器。

CMS工作时主要步骤有初始标记、并发标记、预清理、重新标记、并发清除和并发重置。其中初始标记和重新标记是独占系统资源的,而预清理、并发标记、并发清除和并发重置是可以和用户线程一起执行的。因此它可以在应用程序运行过程中进行垃圾回收。

根据标记清除算法,初始标记、并发标记和重新标记都是为了标记出需要回收的对象。并发清理则是在标记完成后,正是回收垃圾对象。并发重置是指在垃圾回收完成后,重新初始化CMS数据结构和数据,为下一次垃圾回收做好准备。

在整个CMS回收过程中,默认情况下,在并发标记之后,会有一个预清理的操作(也可以设置参数

-XX:CMSPrecleaningEnabled,不进行预清理

)。预清理是并发的,除了为正式清理做准备和检查以外,预清理还会尝试控制一次停顿时间。由于重新标记是独占CPU的,如果新生代GC发生后立即触发一次重新标记,那么一次停顿时间可能很长。为了避免这种情况,预清理时,会可以等待一次新生代GC的发生,然后根据历史性能数据预测一下新生代GC可能发生的时间,然后在当前时间和预测时间的中间时刻,进行重新标记。这样,最大程度上避免新生代GC和重新标记重合,尽可能减少一次停顿时间。

CMS默认启动的并发线程数是(ParallelGCThreads+3)/4,ParallelGCThreads表示GC并发时使用的线程数量,如果使用

当有4个并行线程时,有1个并发线程;
当有5~8个并行线程时,有2个并发线程。

可以通过-XX:ConcGCThreads或者-XX:ParallelCMSThreads来指定。当CPU资源比较紧张时,受到CMS回收器线程的影响,应用系统的性能在垃圾回收阶段可能会非常糟糕。

-XX:CMSInitiatingOccupancyFraction:默认是68

即老年代空间的使用率达到68%时,会执行一次CMS回收。如果应用程序的内存使用率增长过快,在CMS的执行过程中,已经出现了内存不足的情况,此时CMS回收就会失败,虚拟机将启动串行收集器进行垃圾回收。如果这样,应用程序将完全中断,直到垃圾回收完成,这样应用程序的停顿时间可能会较长。

根据应用特点,可以对该值进行调优,如果内存增长缓慢,则可以设置一个稍大的值,大的阈值可以有效降低CMS的触发频率,减少年老代回收的次数可以较为明显地改善应用程序性能。

反之,如果应用程序内存使用率增长很快,则应该降低这个阈值,以避免频繁触发年老代串行收集器。

缺点有空间碎片。

CMS碎片整理

-XX:+UseCMSCompactAtFullCollection:在CMS垃圾收集后,进行一次内存碎片整理。
-XX:CMSFullGCsBeforeCompaction:在进行多少次CMS回收后,进行一次内存压缩。

日志:

1.313 :[GC [1 CMS-initial-mark:69112k    ]]

有关Class的回收

如果希望CMS回收Perm区,则需要打开-XX:+CMSClassUnloadingEnabled开关。如果条件允许,如果条件允许,那么系统会使用CMS的机制回收Perm区的Class数据。

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

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值