一元云購網(wǎng)站怎么做/各平臺推廣費用
前言:
上一篇我們分析了 Minor GC 的發(fā)生過程,因為 GC 日志沒有按我們預(yù)估的思路進行打印,其中打印了 CMS 垃圾回收器的部分日志,本篇我們就來分析一下 CMS 垃圾收集日志。
JVM 系列文章傳送門
初識 JVM(Java 虛擬機)
深入理解 JVM(Java 虛擬機)
一文搞懂 JVM 垃圾回收(JVM GC)
深入理解 JVM 垃圾回收算法
一文搞懂 JVM 垃圾收集器
JVM 調(diào)優(yōu)相關(guān)參數(shù)
JVM 場景面試題【強烈推薦】
JVM 性能調(diào)優(yōu) – 線上應(yīng)用 JVM 內(nèi)存的的預(yù)估設(shè)置【實戰(zhàn)】
JVM 性能調(diào)優(yōu) – 線上應(yīng)用 JVM 內(nèi)存調(diào)優(yōu)【實戰(zhàn)】
JVM 性能調(diào)優(yōu) – 模擬觸發(fā) Minor GC【GC 日志分析】
JVM 性能調(diào)優(yōu) – 模擬觸發(fā) Minor GC(2)【GC 日志分析】
CMS 垃圾收集器出發(fā)的條件
我們知道 CMS 垃圾收集器是老年代的垃圾回收器,因此想要觸發(fā) CMS 垃圾回收,就必須觸發(fā)老年代的 GC,也就是 Full GC,因此 CMS 垃圾收集器出發(fā)的條件就是 Full GC 的觸發(fā)條件,如下:
- 老年代空間不足:Minor GC 后,有對象要晉升到老年代,此時老年代空間也不足,觸發(fā) Full GC。大對象直接在老年代創(chuàng)建的時候,發(fā)現(xiàn)老年代內(nèi)存不足,直接觸發(fā) Full GC。
- 永久代空間不足:永久代默認空間是 21MB,如果永久代空間不足,也會觸發(fā) Full GC。
- 代碼中顯示調(diào)用 System.gc(),這種方式也會觸發(fā) Full GC,但是不會馬上出發(fā) Full GC。
可以知道簡單的方式是調(diào)用 System.gc() 方法,不過本篇我們采用讓老年代空間不足的方式來觸發(fā) Full GC。
JVM 配置
為了盡快觸發(fā) Full GC 我們調(diào)整年輕代老年代的空間占比,具體 JVM 參數(shù)如下:
-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 的參數(shù)在上一篇都逐個解釋過,這里就不在逐個解釋了,這里只簡單陳述一下堆空間內(nèi)存分配情況,新生代初始內(nèi)存空間大小 2MB,新生代最大內(nèi)存空間大小 2MB,初始堆內(nèi)存大小 4MB,最大堆內(nèi)存大小 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("結(jié)束了");}
}
我們創(chuàng)建了 2個 1MB 對象和 1個 2MB 對象,一共 4MB 的對象,整個堆內(nèi)存我只分配了 4MB 的內(nèi)存空間(內(nèi)存占用情況的演進就不演示了),在加上對象的對象頭等占用的內(nèi)存,整個堆內(nèi)存空間肯定是不足的,一定會發(fā)生 Full GC 并發(fā)生 OutOfMemoryError 錯誤,我們啟動程序驗證一下。
啟動程序驗證
啟動程序后控制臺如下:
Exception in thread "main" java.lang.OutOfMemoryError: Java heap spaceat com.order.service.controller.MinorGcDemo.main(MinorGcDemo.java:17)
是按著我們的推理來打印的,控制臺打印了 OutOfMemoryError 錯誤。結(jié)果符合預(yù)期。
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]
Heappar 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 1056768Kclass space used 574K, capacity 596K, committed 640K, reserved 1048576K
GC 日志的開頭同樣是一些 JVM 信息、運行環(huán)境信息、JVM 參數(shù)等,接下來來的兩行看到了我們熟悉的 Minor GC 的日志,再往下就看到了 CMS 相關(guān)的字樣,我們在 JVM 參數(shù)中指定了老年代使用 CMS 垃圾收集器,結(jié)果符合預(yù)期。
CMS 垃圾收集器的工作流程
前面系列文章中對各種垃圾收集器進行了分析,我們這里再回憶一下 CMS 垃圾收集器的工作流程,具體如下:
- 初始標記:暫停所有用戶線程(STW),并記錄所有直接與根(GC ROOTS)對象相連接的對象,這個階段速度很快。
- 并發(fā)標記:同時開始用戶線程和垃圾回收線程,用一個閉包去記錄可達對象,但這個閉包不能保證所有的可達對象,因此工作線程還在工作中,會不斷地更新對象的引用,垃圾回收線程無法保證保證可達性分析的實時性,因此算法會記錄發(fā)生引用更新的對象(這個在前面分享垃圾回收算法的時候提到過)。
- 重新標記:重新標記這個階段是 STW 的,重新標記就是為了處理在并發(fā)標記階段發(fā)生引用變更的對象,因為發(fā)生變更的引用變更的對象畢竟是少數(shù),因此 STW 的時間不會太長,遠比并發(fā)標記階段的時間短,可能會略長于初始標記階段。
- 并發(fā)清除:用戶線程開始工作,垃圾回收線程會開始進行垃圾回收。
總的來說 CMS 垃圾收集器分為四個階段,分別是初始標記、并發(fā)標記、最終標記、并發(fā)清除這四個階段,我們圍繞這四個階段來分析 CMS 的 GC 日志。
分析 CMS 垃圾回收器 GC 日志
分析 CMS 垃圾回收器的 GC 日志我們根據(jù) 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:距離程序運行多久發(fā)生了本次 GC。
- CMS Initial Mark:CMS 初始標記,這個階段會 STW(Stop The World),會找出所有老年代的 GC ROOTS 和被年輕代或者的對象引用的對象。
- 1223K:當前老年代已使用的內(nèi)存。
- (2048K):老年代的總內(nèi)存。
- 1905K:整個堆已經(jīng)使用的內(nèi)存。
- (3904K):整個堆的總內(nèi)存。
- 0.0001422 secs:初始標記耗時,大概 0.1 毫秒,初始標記是很快的。
CMS-concurrent-mark(并發(fā)標記)
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:并發(fā)標記開始。
- CMS-concurrent-mark:并發(fā)標記階段,會掃描整個老年代對象,并標記出活著的對象。
- 0.001/0.001 secs:并發(fā)標記消耗的時間,大概 1毫秒。
CMS-concurrent-preclean(并發(fā)預(yù)清理)
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:并發(fā)預(yù)清理開始。
- CMS-concurrent-preclean:并發(fā)預(yù)清理,主要是做清理之前的一些準備工作。
- 0.000/0.000 secs:并發(fā)預(yù)清理消耗的時間。
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),前面初始標記的時候出現(xiàn)了一次 STW,因為前面是并發(fā)進行標記的,在整個過程中對象的引用發(fā)生了變化,因此需要再次進行 STW 進行標記,該階段的 STW 時長會略大于初始標記階段。
- [YG occupancy: 682 K (1856 K)]:年輕代內(nèi)存情況,682 K 表示年輕代已經(jīng)使用的內(nèi)存,1856 K 表示年輕代總內(nèi)存。
- [Rescan (parallel):重新掃描,也就是 STW 階段。
- 0.0002234 secs:重新掃描,也就是 STW 階段消耗的時間,這里大約是 0.2毫秒(初始標記的時間大概是 0.1 毫秒)。
- weak refs processing:弱引用處理,我們知道如果一個對象只有弱引用,即使系統(tǒng)內(nèi)存充足,垃圾回收器也會立即回收它。
- 0.0000306 secs:處理弱引用消耗的濕巾,大概四0.03毫秒。
- class unloading:卸載未使用的類。
- 0.0002078 secs:類卸載消耗的時間,大概是 0.2毫秒。
- scrub symbol table:清理類元數(shù)據(jù)和內(nèi)部字符串的符號表和字符串表等。
- 0.0000963 secs:清理類元數(shù)據(jù)和內(nèi)部字符串的符號表和字符串表消耗的時間,這里大概是 0.09毫秒。
- CMS-remark: 1223K(2048K)] 1905K(3904K):重新標記之后老年代已經(jīng)使用的內(nèi)存大小為 1223K,老年代總內(nèi)存大小為 2048K,JVM 堆內(nèi)存已使用大小為 1905K,JVM 堆總內(nèi)存大小為 3904K。
- 0.0009979 secs:重新標記持續(xù)的總時間,大概是 0.9毫秒。
CMS-concurrent-sweep(并發(fā)清理)
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:并發(fā)清理開始,應(yīng)用線程同時也在工作。
- CMS-concurrent-sweep:并發(fā)清理垃圾對象,并回收空間。
- 0.000/0.000 secs:并發(fā)清理消耗的時間。
CMS-concurrent-reset(并發(fā)重置)
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 垃圾收集器并發(fā)重置開始,因為是并發(fā),應(yīng)用程序工作線程在同步運行。
- CMS-concurrent-reset:CMS 垃圾收集器進行并發(fā)重置,重新設(shè)置 CMS 垃圾回收算法的中的數(shù)據(jù)結(jié)構(gòu),為下一次垃圾回收做準備。
- 0.000/0.000 secs:并發(fā)重置消耗的時間。
以上就是一個完整的 CMS 垃圾回收的過程,CMS 的垃圾回收日志把我們熟知的 4個階段拆分為了 6個階段,這里提一下 CMS 垃圾回收器使用的是標記-清除算法,因為 CMS 垃圾收集器準求的低停頓,所以標記-清除算法更符合需求。
類的卸載條件
剛剛在分析 CMS GC 日志中有一個階段涉及到了類的卸載,最后這里附上類的卸載條件如下:
- 該類的所有對象都已經(jīng)被 GC,JVM 中不存在任何該類的 Class 實例。
- 加載該類的類加載器 ClassLoad 已經(jīng)被 GC。
- 該類的 Class 對象沒有被任何地方引用,也不能通過反射來訪問該類的任何方法。
類的卸載需要滿足以上三個條件。
總結(jié):本篇分析了 CMS 垃圾回收的過程,一行一行的分析 GC 日志,希望可以幫助到不會看 GC 日志朋友。
如有不正確的地方歡迎各位指出糾正。