JVM 性能调优 -- CMS 垃圾回收器 GC 日志分析【Full GC】

前言:

上一篇我们分析了 Minor GC 的发生过程,因为 GC 日志没有按我们预估的思路进行打印,其中打印了 CMS 垃圾回收器的部分日志,本篇我们就来分析一下 CMS 垃圾收集日志。

JVM 系列文章传送门

初识 JVM(Java 虚拟机)

深入理解 JVM(Java 虚拟机)

一文搞懂 JVM 垃圾回收(JVM GC)

深入理解 JVM 垃圾回收算法

一文搞懂 JVM 垃圾收集器

JVM 调优相关参数

JVM 场景面试题【强烈推荐】

JVM 性能调优 – 线上应用 JVM 内存的的预估设置【实战】

JVM 性能调优 – 线上应用 JVM 内存调优【实战】

JVM 性能调优 – 模拟触发 Minor GC【GC 日志分析】

JVM 性能调优 – 模拟触发 Minor GC(2)【GC 日志分析】

CMS 垃圾收集器出发的条件

我们知道 CMS 垃圾收集器是老年代的垃圾回收器,因此想要触发 CMS 垃圾回收,就必须触发老年代的 GC,也就是 Full GC,因此 CMS 垃圾收集器出发的条件就是 Full GC 的触发条件,如下:

  • 老年代空间不足:Minor GC 后,有对象要晋升到老年代,此时老年代空间也不足,触发 Full GC。大对象直接在老年代创建的时候,发现老年代内存不足,直接触发 Full GC。
  • 永久代空间不足:永久代默认空间是 21MB,如果永久代空间不足,也会触发 Full GC。
  • 代码中显示调用 System.gc(),这种方式也会触发 Full GC,但是不会马上出发 Full GC。

可以知道简单的方式是调用 System.gc() 方法,不过本篇我们采用让老年代空间不足的方式来触发 Full GC。

JVM 配置

为了尽快触发 Full GC 我们调整年轻代老年代的空间占比,具体 JVM 参数如下:

-XX:NewSize=2m -XX:MaxNewSize=2m -Xms4m -Xmx4m -XX:SurvivorRatio=8 -XX:PretenureSizeThreshold=3m -XX:+UseParNewGC -XX:+UseConcMarkSweepGC  -XX:+PrintGCDetails -XX:+PrintGCDateStamps -XX:+PrintGCTimeStamps -Xloggc:gc.log 

上述 JVM 的参数在上一篇都逐个解释过,这里就不在逐个解释了,这里只简单陈述一下堆空间内存分配情况,新生代初始内存空间大小 2MB,新生代最大内存空间大小 2MB,初始堆内存大小 4MB,最大堆内存大小 4MB。

案例代码

案例代码我们还是使用上一篇中使用的案例代码,如下:

@Slf4j
public class MinorGcDemo {

    public static void main(String[] args) {
        byte[] array = new byte[1024 * 1024];
        array = new byte[1024 * 1024];
        array  = new byte[1024 * 1024 * 2];
        log.info("结束了");
    }
}

我们创建了 2个 1MB 对象和 1个 2MB 对象,一共 4MB 的对象,整个堆内存我只分配了 4MB 的内存空间(内存占用情况的演进就不演示了),在加上对象的对象头等占用的内存,整个堆内存空间肯定是不足的,一定会发生 Full GC 并发生 OutOfMemoryError 错误,我们启动程序验证一下。

启动程序验证

启动程序后控制台如下:

Exception in thread "main" java.lang.OutOfMemoryError: Java heap space
	at com.order.service.controller.MinorGcDemo.main(MinorGcDemo.java:17)

是按着我们的推理来打印的,控制台打印了 OutOfMemoryError 错误。结果符合预期。

GC 日志文件详情如下:

Java HotSpot(TM) 64-Bit Server VM (25.121-b13) for windows-amd64 JRE (1.8.0_121-b13), built on Dec 12 2016 18:21:36 by "java_re" with MS VC++ 10.0 (VS2010)
Memory: 4k page, physical 33379636k(6965084k free), swap 61458536k(11599036k free)
CommandLine flags: -XX:InitialHeapSize=4194304 -XX:MaxHeapSize=4194304 -XX:MaxNewSize=2097152 -XX:NewSize=2097152 -XX:OldPLABSize=16 -XX:PretenureSizeThreshold=31457280 -XX:+PrintGC -XX:+PrintGCDateStamps -XX:+PrintGCDetails -XX:+PrintGCTimeStamps -XX:SurvivorRatio=8 -XX:+UseCompressedClassPointers -XX:+UseCompressedOops -XX:+UseConcMarkSweepGC -XX:-UseLargePagesIndividualAllocation -XX:+UseParNewGC 
2024-11-19T20:06:06.078+0800: 0.152: [GC (Allocation Failure) 2024-11-19T20:06:06.078+0800: 0.153: [ParNew: 1655K->192K(1856K), 0.0019913 secs] 1655K->857K(3904K), 0.0021878 secs] [Times: user=0.00 sys=0.00, real=0.00 secs] 
2024-11-19T20:06:06.109+0800: 0.183: [GC (Allocation Failure) 2024-11-19T20:06:06.109+0800: 0.183: [ParNew: 1845K->192K(1856K), 0.0005122 secs] 2510K->1415K(3904K), 0.0005720 secs] [Times: user=0.00 sys=0.00, real=0.00 secs] 
2024-11-19T20:06:06.109+0800: 0.184: [GC (CMS Initial Mark) [1 CMS-initial-mark: 1223K(2048K)] 1905K(3904K), 0.0001422 secs] [Times: user=0.00 sys=0.00, real=0.00 secs] 
2024-11-19T20:06:06.110+0800: 0.184: [CMS-concurrent-mark-start]
2024-11-19T20:06:06.110+0800: 0.185: [CMS-concurrent-mark: 0.001/0.001 secs] [Times: user=0.00 sys=0.00, real=0.00 secs] 
2024-11-19T20:06:06.110+0800: 0.185: [CMS-concurrent-preclean-start]
2024-11-19T20:06:06.110+0800: 0.185: [CMS-concurrent-preclean: 0.000/0.000 secs] [Times: user=0.00 sys=0.00, real=0.00 secs] 
2024-11-19T20:06:06.110+0800: 0.185: [GC (CMS Final Remark) [YG occupancy: 682 K (1856 K)]2024-11-19T20:06:06.110+0800: 0.185: [Rescan (parallel) , 0.0002234 secs]2024-11-19T20:06:06.111+0800: 0.185: [weak refs processing, 0.0000306 secs]2024-11-19T20:06:06.111+0800: 0.185: [class unloading, 0.0002078 secs]2024-11-19T20:06:06.111+0800: 0.185: [scrub symbol table, 0.0003043 secs]2024-11-19T20:06:06.111+0800: 0.186: [scrub string table, 0.0000963 secs][1 CMS-remark: 1223K(2048K)] 1905K(3904K), 0.0009979 secs] [Times: user=0.00 sys=0.00, real=0.00 secs] 
2024-11-19T20:06:06.111+0800: 0.186: [CMS-concurrent-sweep-start]
2024-11-19T20:06:06.112+0800: 0.186: [CMS-concurrent-sweep: 0.000/0.000 secs] [Times: user=0.00 sys=0.00, real=0.00 secs] 
2024-11-19T20:06:06.112+0800: 0.186: [CMS-concurrent-reset-start]
2024-11-19T20:06:06.112+0800: 0.186: [CMS-concurrent-reset: 0.000/0.000 secs] [Times: user=0.00 sys=0.00, real=0.00 secs] 
2024-11-19T20:06:06.146+0800: 0.222: [GC (Allocation Failure) 2024-11-19T20:06:06.146+0800: 0.222: [ParNew: 1856K->192K(1856K), 0.0006090 secs] 3078K->1675K(3904K), 0.0006961 secs] [Times: user=0.14 sys=0.02, real=0.00 secs] 
2024-11-19T20:06:06.147+0800: 0.222: [GC (CMS Initial Mark) [1 CMS-initial-mark: 1483K(2048K)] 1692K(3904K), 0.0001575 secs] [Times: user=0.00 sys=0.00, real=0.00 secs] 
2024-11-19T20:06:06.147+0800: 0.223: [CMS-concurrent-mark-start]
2024-11-19T20:06:06.148+0800: 0.223: [CMS-concurrent-mark: 0.001/0.001 secs] [Times: user=0.00 sys=0.00, real=0.00 secs] 
2024-11-19T20:06:06.148+0800: 0.223: [CMS-concurrent-preclean-start]
2024-11-19T20:06:06.148+0800: 0.223: [CMS-concurrent-preclean: 0.000/0.000 secs] [Times: user=0.00 sys=0.00, real=0.00 secs] 
2024-11-19T20:06:06.148+0800: 0.224: [GC (CMS Final Remark) [YG occupancy: 268 K (1856 K)]2024-11-19T20:06:06.148+0800: 0.224: [Rescan (parallel) , 0.0001757 secs]2024-11-19T20:06:06.148+0800: 0.224: [weak refs processing, 0.0000291 secs]2024-11-19T20:06:06.148+0800: 0.224: [class unloading, 0.0002782 secs]2024-11-19T20:06:06.149+0800: 0.224: [scrub symbol table, 0.0005185 secs]2024-11-19T20:06:06.149+0800: 0.225: [scrub string table, 0.0001561 secs][1 CMS-remark: 1483K(2048K)] 1752K(3904K), 0.0012909 secs] [Times: user=0.00 sys=0.00, real=0.00 secs] 
2024-11-19T20:06:06.149+0800: 0.225: [CMS-concurrent-sweep-start]
2024-11-19T20:06:06.150+0800: 0.225: [CMS-concurrent-sweep: 0.000/0.000 secs] [Times: user=0.00 sys=0.00, real=0.00 secs] 
2024-11-19T20:06:06.150+0800: 0.225: [CMS-concurrent-reset-start]
2024-11-19T20:06:06.150+0800: 0.225: [CMS-concurrent-reset: 0.000/0.000 secs] [Times: user=0.00 sys=0.00, real=0.00 secs] 
2024-11-19T20:06:06.177+0800: 0.252: [GC (Allocation Failure) 2024-11-19T20:06:06.177+0800: 0.252: [ParNew: 1849K->192K(1856K), 0.0006571 secs] 2895K->1470K(3904K), 0.0007809 secs] [Times: user=0.00 sys=0.00, real=0.00 secs] 
2024-11-19T20:06:06.178+0800: 0.253: [GC (CMS Initial Mark) [1 CMS-initial-mark: 1278K(2048K)] 1477K(3904K), 0.0001639 secs] [Times: user=0.00 sys=0.00, real=0.00 secs] 
2024-11-19T20:06:06.178+0800: 0.253: [CMS-concurrent-mark-start]
2024-11-19T20:06:06.179+0800: 0.254: [CMS-concurrent-mark: 0.001/0.001 secs] [Times: user=0.05 sys=0.01, real=0.00 secs] 
2024-11-19T20:06:06.179+0800: 0.254: [CMS-concurrent-preclean-start]
2024-11-19T20:06:06.179+0800: 0.254: [CMS-concurrent-preclean: 0.000/0.000 secs] [Times: user=0.00 sys=0.00, real=0.00 secs] 
2024-11-19T20:06:06.180+0800: 0.256: [GC (CMS Final Remark) [YG occupancy: 229 K (1856 K)]2024-11-19T20:06:06.180+0800: 0.256: [Rescan (parallel) , 0.0001408 secs]2024-11-19T20:06:06.180+0800: 0.256: [weak refs processing, 0.0000134 secs]2024-11-19T20:06:06.180+0800: 0.256: [class unloading, 0.0002569 secs]2024-11-19T20:06:06.181+0800: 0.256: [scrub symbol table, 0.0003719 secs]2024-11-19T20:06:06.181+0800: 0.256: [scrub string table, 0.0000988 secs][1 CMS-remark: 1278K(2048K)] 1508K(3904K), 0.0009640 secs] [Times: user=0.00 sys=0.00, real=0.00 secs] 
2024-11-19T20:06:06.181+0800: 0.257: [CMS-concurrent-sweep-start]
2024-11-19T20:06:06.182+0800: 0.257: [CMS-concurrent-sweep: 0.000/0.000 secs] [Times: user=0.00 sys=0.00, real=0.00 secs] 
2024-11-19T20:06:06.182+0800: 0.257: [CMS-concurrent-reset-start]
2024-11-19T20:06:06.182+0800: 0.257: [CMS-concurrent-reset: 0.000/0.000 secs] [Times: user=0.00 sys=0.00, real=0.00 secs] 
2024-11-19T20:06:06.211+0800: 0.286: [GC (Allocation Failure) 2024-11-19T20:06:06.211+0800: 0.286: [ParNew: 1856K->191K(1856K), 0.0005452 secs] 3044K->1611K(3904K), 0.0006334 secs] [Times: user=0.00 sys=0.00, real=0.00 secs] 
2024-11-19T20:06:06.211+0800: 0.287: [GC (CMS Initial Mark) [1 CMS-initial-mark: 1419K(2048K)] 1645K(3904K), 0.0002982 secs] [Times: user=0.00 sys=0.00, real=0.00 secs] 
2024-11-19T20:06:06.212+0800: 0.287: [CMS-concurrent-mark-start]
2024-11-19T20:06:06.213+0800: 0.288: [CMS-concurrent-mark: 0.001/0.001 secs] [Times: user=0.00 sys=0.00, real=0.00 secs] 
2024-11-19T20:06:06.213+0800: 0.288: [CMS-concurrent-preclean-start]
2024-11-19T20:06:06.213+0800: 0.288: [CMS-concurrent-preclean: 0.000/0.000 secs] [Times: user=0.00 sys=0.00, real=0.00 secs] 
2024-11-19T20:06:06.213+0800: 0.288: [GC (CMS Final Remark) [YG occupancy: 284 K (1856 K)]2024-11-19T20:06:06.213+0800: 0.288: [Rescan (parallel) , 0.0002925 secs]2024-11-19T20:06:06.213+0800: 0.288: [weak refs processing, 0.0000151 secs]2024-11-19T20:06:06.213+0800: 0.288: [class unloading, 0.0002927 secs]2024-11-19T20:06:06.214+0800: 0.289: [scrub symbol table, 0.0004106 secs]2024-11-19T20:06:06.214+0800: 0.289: [scrub string table, 0.0000977 secs][1 CMS-remark: 1419K(2048K)] 1703K(3904K), 0.0011965 secs] [Times: user=0.00 sys=0.00, real=0.00 secs] 
2024-11-19T20:06:06.214+0800: 0.289: [CMS-concurrent-sweep-start]
2024-11-19T20:06:06.214+0800: 0.290: [CMS-concurrent-sweep: 0.000/0.000 secs] [Times: user=0.00 sys=0.00, real=0.00 secs] 
2024-11-19T20:06:06.214+0800: 0.290: [CMS-concurrent-reset-start]
2024-11-19T20:06:06.214+0800: 0.290: [CMS-concurrent-reset: 0.000/0.000 secs] [Times: user=0.00 sys=0.00, real=0.00 secs] 
2024-11-19T20:06:06.234+0800: 0.309: [GC (Allocation Failure) 2024-11-19T20:06:06.234+0800: 0.310: [ParNew (promotion failed): 1521K->1521K(1856K), 0.0009737 secs]2024-11-19T20:06:06.235+0800: 0.311: [CMS: 1520K->1648K(2048K), 0.0036692 secs] 2855K->1648K(3904K), [Metaspace: 5082K->5082K(1056768K)], 0.0047468 secs] [Times: user=0.00 sys=0.00, real=0.01 secs] 
2024-11-19T20:06:06.239+0800: 0.314: [GC (CMS Initial Mark) [1 CMS-initial-mark: 1648K(2048K)] 2672K(3904K), 0.0007071 secs] [Times: user=0.00 sys=0.00, real=0.00 secs] 
2024-11-19T20:06:06.240+0800: 0.315: [CMS-concurrent-mark-start]
2024-11-19T20:06:06.240+0800: 0.315: [GC (Allocation Failure) 2024-11-19T20:06:06.240+0800: 0.316: [ParNew: 1024K->1024K(1856K), 0.0000221 secs]2024-11-19T20:06:06.240+0800: 0.316: [CMS2024-11-19T20:06:06.249+0800: 0.325: [CMS-concurrent-mark: 0.001/0.009 secs] [Times: user=0.03 sys=0.00, real=0.01 secs] 
 (concurrent mode failure): 1648K->1648K(2048K), 0.0120389 secs] 2672K->2672K(3904K), [Metaspace: 5082K->5082K(1056768K)], 0.0121408 secs] [Times: user=0.03 sys=0.00, real=0.01 secs] 
2024-11-19T20:06:06.253+0800: 0.328: [Full GC (Allocation Failure) 2024-11-19T20:06:06.253+0800: 0.328: [CMS: 1648K->1572K(2048K), 0.0025655 secs] 2672K->2596K(3904K), [Metaspace: 5082K->5082K(1056768K)], 0.0026041 secs] [Times: user=0.00 sys=0.00, real=0.00 secs] 
Heap
 par new generation   total 1856K, used 1072K [0x00000000ffc00000, 0x00000000ffe00000, 0x00000000ffe00000)
  eden space 1664K,  64% used [0x00000000ffc00000, 0x00000000ffd0c3b8, 0x00000000ffda0000)
  from space 192K,   0% used [0x00000000ffda0000, 0x00000000ffda0000, 0x00000000ffdd0000)
  to   space 192K,   0% used [0x00000000ffdd0000, 0x00000000ffdd0000, 0x00000000ffe00000)
 concurrent mark-sweep generation total 2048K, used 1572K [0x00000000ffe00000, 0x0000000100000000, 0x0000000100000000)
 Metaspace       used 5113K, capacity 5224K, committed 5504K, reserved 1056768K
  class space    used 574K, capacity 596K, committed 640K, reserved 1048576K

GC 日志的开头同样是一些 JVM 信息、运行环境信息、JVM 参数等,接下来来的两行看到了我们熟悉的 Minor GC 的日志,再往下就看到了 CMS 相关的字样,我们在 JVM 参数中指定了老年代使用 CMS 垃圾收集器,结果符合预期。

CMS 垃圾收集器的工作流程

前面系列文章中对各种垃圾收集器进行了分析,我们这里再回忆一下 CMS 垃圾收集器的工作流程,具体如下:

  • 初始标记:暂停所有用户线程(STW),并记录所有直接与根(GC ROOTS)对象相连接的对象,这个阶段速度很快。
  • 并发标记:同时开始用户线程和垃圾回收线程,用一个闭包去记录可达对象,但这个闭包不能保证所有的可达对象,因此工作线程还在工作中,会不断地更新对象的引用,垃圾回收线程无法保证保证可达性分析的实时性,因此算法会记录发生引用更新的对象(这个在前面分享垃圾回收算法的时候提到过)。
  • 重新标记:重新标记这个阶段是 STW 的,重新标记就是为了处理在并发标记阶段发生引用变更的对象,因为发生变更的引用变更的对象毕竟是少数,因此 STW 的时间不会太长,远比并发标记阶段的时间短,可能会略长于初始标记阶段。
  • 并发清除:用户线程开始工作,垃圾回收线程会开始进行垃圾回收。

总的来说 CMS 垃圾收集器分为四个阶段,分别是初始标记、并发标记、最终标记、并发清除这四个阶段,我们围绕这四个阶段来分析 CMS 的 GC 日志。

分析 CMS 垃圾回收器 GC 日志

分析 CMS 垃圾回收器的 GC 日志我们根据 CMS 垃圾回收器的工作流程来分析。

CMS Initial Mark(初始标记)

2024-11-19T20:06:06.109+0800: 0.184: [GC (CMS Initial Mark) [1 CMS-initial-mark: 1223K(2048K)] 1905K(3904K), 0.0001422 secs] [Times: user=0.00 sys=0.00, real=0.00 secs]
  • 2024-11-19T20:06:06.109+0800:GC 日志日志的时间。
  • 0.184:距离程序运行多久发生了本次 GC。
  • CMS Initial Mark:CMS 初始标记,这个阶段会 STW(Stop The World),会找出所有老年代的 GC ROOTS 和被年轻代或者的对象引用的对象。
  • 1223K:当前老年代已使用的内存。
  • (2048K):老年代的总内存。
  • 1905K:整个堆已经使用的内存。
  • (3904K):整个堆的总内存。
  • 0.0001422 secs:初始标记耗时,大概 0.1 毫秒,初始标记是很快的。

CMS-concurrent-mark(并发标记)

2024-11-19T20:06:06.110+0800: 0.184: [CMS-concurrent-mark-start]
2024-11-19T20:06:06.110+0800: 0.185: [CMS-concurrent-mark: 0.001/0.001 secs] [Times: user=0.00 sys=0.00, real=0.00 secs] 
  • CMS-concurrent-mark-start:并发标记开始。
  • CMS-concurrent-mark:并发标记阶段,会扫描整个老年代对象,并标记出活着的对象。
  • 0.001/0.001 secs:并发标记消耗的时间,大概 1毫秒。

CMS-concurrent-preclean(并发预清理)

2024-11-19T20:06:06.110+0800: 0.185: [CMS-concurrent-preclean-start]
2024-11-19T20:06:06.110+0800: 0.185: [CMS-concurrent-preclean: 0.000/0.000 secs] [Times: user=0.00 sys=0.00, real=0.00 secs] 
  • CMS-concurrent-preclean-start:并发预清理开始。
  • CMS-concurrent-preclean:并发预清理,主要是做清理之前的一些准备工作。
  • 0.000/0.000 secs:并发预清理消耗的时间。

CMS Final Remark(重新标记)

2024-11-19T20:06:06.110+0800: 0.185: [GC (CMS Final Remark) [YG occupancy: 682 K (1856 K)]2024-11-19T20:06:06.110+0800: 0.185: [Rescan (parallel) , 0.0002234 secs]2024-11-19T20:06:06.111+0800: 0.185: [weak refs processing, 0.0000306 secs]2024-11-19T20:06:06.111+0800: 0.185: [class unloading, 0.0002078 secs]2024-11-19T20:06:06.111+0800: 0.185: [scrub symbol table, 0.0003043 secs]2024-11-19T20:06:06.111+0800: 0.186: [scrub string table, 0.0000963 secs][1 CMS-remark: 1223K(2048K)] 1905K(3904K), 0.0009979 secs] [Times: user=0.00 sys=0.00, real=0.00 secs] 
  • CMS Final Remark:重新标记,这个阶段会是第二个 STW(Stop The World),前面初始标记的时候出现了一次 STW,因为前面是并发进行标记的,在整个过程中对象的引用发生了变化,因此需要再次进行 STW 进行标记,该阶段的 STW 时长会略大于初始标记阶段。
  • [YG occupancy: 682 K (1856 K)]:年轻代内存情况,682 K 表示年轻代已经使用的内存,1856 K 表示年轻代总内存。
  • [Rescan (parallel):重新扫描,也就是 STW 阶段。
  • 0.0002234 secs:重新扫描,也就是 STW 阶段消耗的时间,这里大约是 0.2毫秒(初始标记的时间大概是 0.1 毫秒)。
  • weak refs processing:弱引用处理,我们知道如果一个对象只有弱引用,即使系统内存充足,垃圾回收器也会立即回收它。
  • 0.0000306 secs:处理弱引用消耗的湿巾,大概四0.03毫秒。
  • class unloading:卸载未使用的类。
  • 0.0002078 secs:类卸载消耗的时间,大概是 0.2毫秒。
  • scrub symbol table:清理类元数据和内部字符串的符号表和字符串表等。
  • 0.0000963 secs:清理类元数据和内部字符串的符号表和字符串表消耗的时间,这里大概是 0.09毫秒。
  • CMS-remark: 1223K(2048K)] 1905K(3904K):重新标记之后老年代已经使用的内存大小为 1223K,老年代总内存大小为 2048K,JVM 堆内存已使用大小为 1905K,JVM 堆总内存大小为 3904K。
  • 0.0009979 secs:重新标记持续的总时间,大概是 0.9毫秒。

CMS-concurrent-sweep(并发清理)

2024-11-19T20:06:06.111+0800: 0.186: [CMS-concurrent-sweep-start]
2024-11-19T20:06:06.112+0800: 0.186: [CMS-concurrent-sweep: 0.000/0.000 secs] [Times: user=0.00 sys=0.00, real=0.00 secs] 
  • CMS-concurrent-sweep-start:并发清理开始,应用线程同时也在工作。
  • CMS-concurrent-sweep:并发清理垃圾对象,并回收空间。
  • 0.000/0.000 secs:并发清理消耗的时间。

CMS-concurrent-reset(并发重置)

2024-11-19T20:06:06.112+0800: 0.186: [CMS-concurrent-reset-start]
2024-11-19T20:06:06.112+0800: 0.186: [CMS-concurrent-reset: 0.000/0.000 secs] [Times: user=0.00 sys=0.00, real=0.00 secs] 
  • [CMS-concurrent-reset-start]:CMS 垃圾收集器并发重置开始,因为是并发,应用程序工作线程在同步运行。
  • CMS-concurrent-reset:CMS 垃圾收集器进行并发重置,重新设置 CMS 垃圾回收算法的中的数据结构,为下一次垃圾回收做准备。
  • 0.000/0.000 secs:并发重置消耗的时间。

以上就是一个完整的 CMS 垃圾回收的过程,CMS 的垃圾回收日志把我们熟知的 4个阶段拆分为了 6个阶段,这里提一下 CMS 垃圾回收器使用的是标记-清除算法,因为 CMS 垃圾收集器准求的低停顿,所以标记-清除算法更符合需求。

类的卸载条件

刚刚在分析 CMS GC 日志中有一个阶段涉及到了类的卸载,最后这里附上类的卸载条件如下:

  • 该类的所有对象都已经被 GC,JVM 中不存在任何该类的 Class 实例。
  • 加载该类的类加载器 ClassLoad 已经被 GC。
  • 该类的 Class 对象没有被任何地方引用,也不能通过反射来访问该类的任何方法。

类的卸载需要满足以上三个条件。

总结:本篇分析了 CMS 垃圾回收的过程,一行一行的分析 GC 日志,希望可以帮助到不会看 GC 日志朋友。

如有不正确的地方欢迎各位指出纠正。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:/a/924307.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

云计算的计算包括哪些内容

‌云计算的计算主要包括以下几种类型‌: ‌分布式计算‌:分布式计算是一种计算方法,它将大型问题分解成多个小任务,然后分配给多个计算机进行处理。这种方法可以提高计算效率和可靠性‌1。‌并行计算‌:并行计算是同时…

PICO 获取设备号 SN码

Unity版本 2020.3.42f1c1PICO SDK版本PICO Unity Integration SDK-3.0.5-20241105Pico设备pico 4ultra 注意 此api暂时只测试企业版本 pico 4ultra 代码 using Unity.XR.PICO.TOBSupport;private void Awake() {bool result PXR_Enterprise.InitEnterpriseService();Debug.L…

如何制作项目网页

一、背景 许多论文里经常会有这样一句话Supplementary material can be found at https://hri-eu.github.io/Lami/,这个就是将论文中的内容或者补充视频放到一个网页上,以更好的展示他们的工作。因此,这里介绍下如何使用前人提供的模板制作我…

圆域函数的傅里叶变换和傅里叶逆变换

空域圆域函数的傅里叶变换 空域圆域函数(也称为空间中的圆形区域函数)通常指的是在二维空间中,以原点为中心、半径为 a a a的圆内取值为1,圆外取值为0的函数。这种函数可以表示为: f ( x , y ) { 1 if x 2 y 2 ≤ …

云技术-docker

声明! 学习视频来自B站up主 **泷羽sec** 有兴趣的师傅可以关注一下,如涉及侵权马上删除文章,笔记只是方便各位师傅的学习和探讨,文章所提到的网站以及内容,只做学习交流,其他均与本人以及泷羽sec团…

win10中使用ffmpeg的filter滤镜

1 给视频加文字水印 1.1 添加播放时间 ffmpeg -i input.mp4 -vf "drawtextfontfileC\\:/Windows/fonts/consola.ttf:fontsize30:fontcolorwhite:timecode00\:00\:00\:00:rate25:textTCR\::boxcolor0x000000AA:box1:x20:y20" -y output.mp4 在视频的x20:y20位置添加t…

MyBatis事务管理-附案例代码

一、MyBatis事务管理 SqlSession对象 getMapper(DAO.class):获取Mapper(DAO接口的实体类)事务管理 1.1 手动提交事务 手动事务管理 当我们获取sqlSession对象时,就默认开启了事务; 当一系列业务操作完成之后,我们需要…

QChart数据可视化

目录 一、QChart基本介绍 1.1 QChart基本概念与用途 1.2 主要类的介绍 1.2.1 QChartView类 1.2.2 QChart类 1.2.3QAbstractSeries类 1.2.4 QAbstractAxis类 1.2.5 QLegendMarker 二、与图表交互 1. 动态绘制数据 2. 深入数据 3. 缩放和滚动 4. 鼠标悬停 三、主题 …

互联网视频推拉流EasyDSS视频直播点播平台视频转码有哪些技术特点和应用?

视频转码本质上是一个先解码再编码的过程。在转码过程中,原始视频码流首先被解码成原始图像数据,然后再根据目标编码标准、分辨率、帧率、码率等参数重新进行编码。这样,转换前后的码流可能遵循相同的视频编码标准,也可能不遵循。…

黑马程序员Java项目实战《苍穹外卖》Day01

苍穹外卖-day01 课程内容 软件开发整体介绍苍穹外卖项目介绍开发环境搭建导入接口文档Swagger 项目整体效果展示: ​ 管理端-外卖商家使用 ​ 用户端-点餐用户使用 当我们完成该项目的学习,可以培养以下能力: 1. 软件开发整体介绍 作为一…

使用phpStudy小皮面板模拟后端服务器,搭建H5网站运行生产环境

一.下载安装小皮 小皮面板官网下载网址:小皮面板(phpstudy) - 让天下没有难配的服务器环境! 安装说明(特别注意) 1. 安装路径不能包含“中文”或者“空格”,否则会报错(例如错误提示:Cant cha…

No.1 杀戮尖塔Godot复刻|项目概述|场景设置

项目概述 含有47个脚本文件,包括1185行代码,最长的脚本有111行 Battle Node——战斗节点 start_battle()——开始战斗turn management——管理回合win/lose conditions——识别输赢条件 EnemyHandler——敌人处理程序 enemy turn management——管理…

化工专业如何转软工

在当今数字化时代,跨考软件工程已经成为许多理工科学子的一个重要选择。化工专业的同学有着扎实的理工科基础,尤其是数学功底,这对于转向计算机领域是一个天然的优势。让我们详细探讨如何规划这段跨考之路。 编程语言的选择是入门的第一步。…

《Opencv》基础操作<1>

目录 一、Opencv简介 主要特点: 应用领域: 二、基础操作 1、模块导入 2、图片的读取和显示 (1)、读取 (2)、显示 3、 图片的保存 4、获取图像的基本属性 5、图像转灰度图 6、图像的截取 7、图…

论文阅读:A Software Platform for Manipulating theCamera Imaging Pipeline

论文代码开源链接: A Software Platform for Manipulating the Camera Imaging Pipelinehttps://karaimer.github.io/camera-pipeline/摘要:论文提出了一个Pipline软件平台,可以方便地访问相机成像Pipline的每个阶段。该软件允许修改单个模块…

ChatGPT的应用场景:开启无限可能的大门

ChatGPT的应用场景:开启无限可能的大门 随着人工智能技术的快速发展,自然语言处理领域迎来了前所未有的突破。其中,ChatGPT作为一款基于Transformer架构的语言模型,凭借其强大的语言理解和生成能力,在多个行业和场景中展现出了广泛的应用潜力。以下是ChatGPT八个最具代表…

音视频-什么是帧,视频为什么要编码

帧就是动画中的一张图片,这相当于电影胶片上的一个镜头,一帧就是一幅静止的画面,连续的帧就形成了我们看到的动画和视频。 但是直接采集后没经过处理的视频,其实是没有办法真正在互联网上进行传输的。以一张1920乘1080的图片为例&…

“蜀道山”高校联合公益赛 Web (部分)

文章目录 奶龙牌WAF海关警察训练平台恶意代码检测器 奶龙牌WAF <?php if ($_SERVER[REQUEST_METHOD] POST && isset($_FILES[upload_file])) {$file $_FILES[upload_file];if ($file[error] UPLOAD_ERR_OK) {$name isset($_GET[name]) ? $_GET[name] : basen…

【JavaEE初阶 — 网络原理】初识网络原理

目录 1. 网络发展史 1.1 独立模式 1.2 网络互连 1.2.1 网络互联的背景 1.2.2 网络互联的定义 1.3 局域网LAN 1.4 广域网WAN 2. 网络通信基础 2.1 IP地址 2.2 端口号 2.3 认识协议 2.4 五元组 2.5 协议分层 2.5.1 分…

Linux的介绍及虚拟机centOS系统的下载与应用

1、什么是Linux Linux 是一种类 Unix 操作系统&#xff0c;它的内核&#xff08;Kernel&#xff09;由 Linus Torvalds 于 1991 年首次发布。作为一个开源、免费的操作系统&#xff0c;Linux 被广泛用于服务器、桌面计算机、嵌入式设备、移动设备等各种场景。 1、操作系统 操…