聊聊几种常见 GC 简介

 2023-02-19
原文作者:我犟不过你 原文地址:https://juejin.cn/post/7003211326671568933

在springboot-admin当中,大概会有以下几种类型的gc出现,本文我们看看他们分别是什么意思。

本文使用的垃圾收集器是jdk1.8的PS+PO。

Allocation Failure

顾名思义,就是内存分配失败导致的GC,常见于年轻代当中。

    [GC (Allocation Failure) [PSYoungGen: 196608K->14305K(229376K)] 196608K->14385K(491520K), 0.0212573 secs] [Times: user=0.02 sys=0.00, real=0.02 secs]

GCLocker Initiated GC

使用JNI临界区的方式操作数组或者字符串时,为了防止GC过程中jarray或者jstring发生位移,而导致数组指针失效,需要保持它们在JVM Heap中的地址在JNI Critical过程中保持不变。于是JVM实现了GC_locker,用于JNI Critical内阻止其他GC的发生。

当GCLocker被激活且需要发生GC的时候(这里是否需要GC是各种GC发生时,调用GCLocker::check_active_before_gc()函数check并设置_needs_gc = true的),就会阻塞其他线程进入JNI临界区;并且在最后一个位于JNI临界区的线程退出临界区时,发起一次CGCause为_gc_locker的GC。这里解释了GCLocker Initiated GC发生的原委。

Ergonomics

在JVM中的垃圾收集器中的Ergonomics就是负责自动的调解gc暂停时间和吞吐量之间的平衡,使你的虚拟机性能更好的一种做法。

简单说就是内存在进行分配的时候,会通过一些算法,预估是否会出现无法分配的问题。如果符合无法分配预估值,会提前进行一次gc。

    [Full GC (Ergonomics) [PSYoungGen: 544K->0K(9216K)] [ParOldGen: 6144K->6627K(10240K)] 6688K->6627K(19456K), [Metaspace: 3286K->3286K(1056768K)], 0.0063048 secs] [Times: user=0.01 sys=0.00, real=0.01 secs]

Metadata GC Threshold

这个gc主要发生的条件是元空间,也就是Metadata的参数设置问题。

通常根据我们学习的JVM只是,元空间使用的是本地内存,所以应该与当前服务器的最大内存有关。

但实际不是这样的,在jdk1.8中,如果不设置元空间的大小,会有一个默认值是 21M

所以需要我们启动的时候指定一个元空间大小:

    -XX:MetaspaceSize=128M

GC日志如下所示:

    [GC (Metadata GC Threshold) [PSYoungGen: 170464K->16894K(229376K)] 170544K->16982K(491520K), 0.0213845 secs] [Times: user=0.02 sys=0.00, real=0.02 secs] 
    [Full GC (Metadata GC Threshold) [PSYoungGen: 16894K->0K(229376K)] [ParOldGen: 88K->16517K(262144K)] 16982K->16517K(491520K), [Metaspace: 20538K->20538K(1067008K)], 0.0345880 secs] [Times: user=0.23 sys=0.02, real=0.04 secs]