JVM的垃圾收集器,GC日志分析(HotSpot,JDK1.8附上GC思维导图)

本文深入探讨JVM的垃圾回收机制,包括不同类型的垃圾收集器如串行、并行、CMS及G1收集器的工作原理,以及如何通过JVM参数进行优化。涵盖Server与Client类型JVM的区别,垃圾收集器的分类,以及GC日志分析。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

JVM的垃圾收集器,GC日志分析(HotSpot)

常用GC命令和概念思维导图

-server与-client参数
  1. Server jvm的初始空间会大一些,默认使用的是并行垃圾回收器,启动慢,运行快
  2. Client jvm相对保守一些,初始空间会小一些,使用串行垃圾回收器,他的目标是为了让JVM的启动速度更快,但是运行速度会比Server jvm慢一些
    JVM在启动的时候,会根据硬件和操作系统自动选择使用Server还是Client类型的JVM
    ![在这里插入图片描述](https://img-blog.csdnimg.cn/20200513155517380.png
    JVM选择模式:
  • 32位操作系统:
    如果操作系统为windows系统,不论硬件配置如何,都默认使用Client类型的JVM
    如果是其他操作系统,机器配置有2GB以上的内存同时具有2 个以上的CPU的话,默认使用Server类型的JVM,否则使用Client类型的JVM
  • 64位操作系统
    只有server类型的JVM,不支持Client类型的JVM

垃圾收集器分类 :串行回收器、并行回收器、CMS收集器、G1垃圾收集器

jdk1.7 默认垃圾收集器Parallel Scavenge(新生代)+Parallel Old(老年代)

jdk1.8 默认垃圾收集器Parallel Scavenge(新生代)+Parallel Old(老年代)

jdk1.9 默认垃圾收集器**G1

1.串行垃圾收集器

  1. 最古老而且稳定

  2. 单线程没有线程切换的开销

  3. 对于并行能力较弱(cpu核数少)的pc来说效果好。

  4. 单线程进行垃圾回收,进行垃圾回收时,只有一个线程在工作,并且java应用中的所有线程都要暂停,等待垃圾回收完成。这种现象被称之为STW(STOP-THE-WORLD)

    由于这种特性,会暂停其他线程,在实时性要求高德应用场景,交互性比较高的场景中,这种现象是不能被接受的)

    使用方法:-XX:+UseSerialGC指定使用新生代串行回收器和老年代串行回收器。
    在这里插入图片描述

    (附上GC日志打印,-XX:+PrintGCDetails

    -XX:+PrintGC 输出GC日志
    -XX:+PrintGCDetails 输出GC的详细日志
    -XX:+PrintGCTimeStamps 输出GC的时间戳(以基准时间的形式)
    -XX:+PrintGCDateStamps 输出GC的时间戳(以日期的形式,如 2013-05-04T21:53:59.234+0800)
    -XX:+PrintHeapAtGC 在进行GC的前后打印出堆的信息
     -Xloggc:../logs/gc.log 日志文件的输出路径
    
[GC (Allocation Failure) [DefNew: 78016K->6102K(78016K), 0.0208594 secs] 81477K->18113K(251456K), 0.0208838 secs] [Times: user=0.02 sys=0.00, real=0.02 secs] 
 
[Full GC (Metadata GC Threshold) [Tenured: 12011K->16345K(173440K), 0.0234272 secs] 23264K->16345K(251456K), [Metaspace: 20110K->20110K(1067008K)], 0.0234720 secs] [Times: user=0.03 sys=0.00, real=0.02 secs] 
 

GC日志信息解读:

GC**:

表明进行了一次垃圾回收,前面没有Full修饰,表明这是一次Minor GC ,注意它不表示只GC新生代,并且现有的不管是新生代还是老年代都会STW。

Allocation Failure:

表明本次引起GC的原因是因为在年轻代中没有足够的空间能够存储新的数据了。

DefNew
表示使用的是串行垃圾收集器。

4416K->512K(4928K)
表示,年轻代GC前,占有4416K内存,GC后,占有512K内存,总大小4928K

0.0046102 secs
表示,GC所用的时间,单位为毫秒。

4416K->1973K(15872K)
表示,GC前,堆内存占有4416K,GC后,占有1973K,总大小为15872K

Full GC的Metadata GC Threshold
元空间(JDK1.8 默认21M)发生GC ,

(为了避免多次发生该GC,可以调大元空间内存,启动参数为-XX:MetaspaceSize 根据实际需求调动)

2.并行垃圾收集器

并行收集器:
ParNew:是使用-XX:+UseParNewGC(新生代使用并行收集器,老年代使用串行回收收集器)

或者-XX:+UseConcMarkSweepGC(新生代使用并行收集器,老年代使用CMS)。

打印出的信息
[GC (Allocation Failure) [ParNew: 4416K->512K(4928K), 0.0032106 secs] 4416K-
>1988K(15872K), 0.0032697 secs] [Times: user=0.00 sys=0.00, real=0.00 secs]

由以上信息可以看出, ParNew: 使用的是ParNew收集器。其他信息和串行收集器一致。

ParallelGC垃圾收集器(1.8默认,该测试未配置jvm收集器信息)

ParallelGC收集器工作机制和ParNewGC收集器一样,只是在此基础之上,新增了两个和系统吞吐量相关的参数,
使得其使用起来更加的灵活和高效。
相关参数如下:
-XX:+UseParallelGC
年轻代使用ParallelGC垃圾回收器,老年代使用串行回收器。
-XX:+UseParallelOldGC
年轻代使用ParallelGC垃圾回收器,老年代使用ParallelOldGC垃圾回收器。
-XX:MaxGCPauseMillis
设置最大的垃圾收集时的停顿时间,单位为毫秒
需要注意的时,ParallelGC为了达到设置的停顿时间,可能会调整堆大小或其他的参数,如果堆的大小
设置的较小,就会导致GC工作变得很频繁,反而可能会影响到性能。
该参数使用需谨慎。
-XX:GCTimeRatio
设置垃圾回收时间占程序运行时间的百分比,公式为1/(1+n)。
它的值为0~100之间的数字,默认值为99,也就是垃圾回收时间不能超过1%
-XX:UseAdaptiveSizePolicy
自适应GC模式,垃圾回收器将自动调整年轻代、老年代等参数,达到吞吐量、堆大小、停顿时间之间的
平衡。
一般用于,手动调整参数比较困难的场景,让收集器自动进行调整。
[GC (Allocation Failure) [PSYoungGen: 474147K->29357K(555520K)] 536897K->92115K(899072K), 0.0204850 secs] [Times: user=0.09 sys=0.00, real=0.02 secs] 


[Full GC (Metadata GC Threshold) [PSYoungGen: 28801K->0K(417280K)] [ParOldGen: 46181K->62725K(343552K)] 74983K->62725K(760832K), [Metaspace: 94058K->94058K(1136640K)], 0.1706496 secs] [Times: user=0.58 sys=0.02, real=0.17 secs] 

由以上信息可以看出,

PSYoungGen:年轻代 使用的是ParallelGC收集器。ParOldGen老年代使用的是ParallelGC收集器(在执行fullGC时会出现项目停顿(卡顿)现象) :其他信息和串行收集器一致。

3.CMS垃圾收集器

CMS全称 Concurrent Mark Sweep,是一款并发的、使用标记-清除算法的垃圾回收器,该回收器是针对老年代垃圾回收的,通过参数-XX:+UseConcMarkSweepGC进行设置。

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-Klj5LKj2-1589263390680)(C:\Users\VIolet\AppData\Roaming\Typora\typora-user-images\image-20200512120956882.png)]

初始化标记(CMS-initial-mark) ,标记root,会导致stw;
并发标记(CMS-concurrent-mark),与用户线程同时运行;
预清理(CMS-concurrent-preclean),与用户线程同时运行; 重新标记(CMS-remark) ,会导致stw;
并发清除(CMS-concurrent-sweep),与用户线程同时运行;
调整堆大小,设置CMS在清理之后进行内存压缩,目的是清理内存中的碎片;
并发重置状态等待下次CMS的触发(CMS-concurrent-reset),与用户线程同时运行

    #设置启动参数
    -XX:+UseConcMarkSweepGC -XX:+PrintGCDetails -Xms16m -Xmx16m
    #运行日志
    [GC (Allocation Failure) [ParNew: 4926K->512K(4928K), 0.0041843 secs] 9424K-
    >6736K(15872K), 0.0042168 secs] [Times: user=0.00 sys=0.00, real=0.00 secs]
    #第一步,初始标记
    [GC (CMS Initial Mark) [1 CMS-initial-mark: 6224K(10944K)] 6824K(15872K), 0.0004209
    secs] [Times: user=0.00 sys=0.00, real=0.00 secs]
    #第二步,并发标记
    [CMS-concurrent-mark-start]
    [CMS-concurrent-mark: 0.002/0.002 secs] [Times: user=0.00 sys=0.00, real=0.00 secs]
    #第三步,预处理
    [CMS-concurrent-preclean-start]
    [CMS-concurrent-preclean: 0.000/0.000 secs] [Times: user=0.00 sys=0.00, real=0.00 secs]
    #第四步,重新标记
    [GC (CMS Final Remark) [YG occupancy: 1657 K (4928 K)][Rescan (parallel) , 0.0005811
    secs][weak refs processing, 0.0000136 secs][class unloading, 0.0003671 secs][scrub
    symbol table, 0.0006813 secs][scrub string table, 0.0001216 secs][1 CMS-remark:
    6224K(10944K)] 7881K(15872K), 0.0018324 secs] [Times: user=0.00 sys=0.00, real=0.00
    secs]
    #第五步,并发清理
    [CMS-concurrent-sweep-start]
    [CMS-concurrent-sweep: 0.004/0.004 secs] [Times: user=0.00 sys=0.00, real=0.00 secs]
    #第六步,重置
    [CMS-concurrent-reset-start]
    [CMS-concurrent-reset: 0.000/0.000 secs] [Times: user=0.00 sys=0.00, real=0.00 secs]

4.G1收集器(这里使用我其他文章)

https://blog.youkuaiyun.com/Violet_201903027/article/details/106074870

总结GC收集器使用的算法 :

新生代收集器使用的收集器:Serial、PraNew、Parallel Scavenge

老年代收集器使用的收集器:Serial Old、Parallel Old、CMS

1.Serial收集器(复制算法)

新生代单线程收集器,标记和清理都是单线程,优点是简单高效。

2.Serial Old收集器(标记-整理算法)

老年代单线程收集器,Serial收集器的老年代版本。

3.ParNew收集器(停止-复制算法)

新生代收集器,可以认为是Serial收集器的多线程版本,在多核CPU环境下有着比Serial更好的表现。

4.Parallel Scavenge收集器(停止-复制算法)

并行收集器,追求高吞吐量,高效利用CPU。吞吐量一般为99%, 吞吐量= 用户线程时间/(用户线程时间+GC线程时间)。适合后台应用等对交互相应要求不高的场景。

5.Parallel Old收集器(停止-复制算法)

Parallel Scavenge收集器的老年代版本,并行收集器,吞吐量优先

6.CMS(Concurrent Mark Sweep)收集器(标记-清理算法)

高并发、低停顿,追求最短GC回收停顿时间,cpu占用比较高,响应时间快,停顿时间短,多核cpu 追求高响应时间的选择
7.G1 整体采用标记-整理算法,局部是通过是通过复制算法,不会产生内存碎片
G1 能充分利用多 CPU、多核环境硬件优势,尽量缩短 STW。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值