日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當(dāng)前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

JVM:GC日志解读

發(fā)布時(shí)間:2025/3/21 编程问答 27 豆豆
生活随笔 收集整理的這篇文章主要介紹了 JVM:GC日志解读 小編覺得挺不錯(cuò)的,現(xiàn)在分享給大家,幫大家做個(gè)參考.
  • 深入理解Java虛擬機(jī)

    • [JVM]Java內(nèi)存區(qū)域與垃圾收集 - 思維導(dǎo)圖
    • [JVM]類加載機(jī)制 - 思維導(dǎo)圖
    • [JVM]OOM實(shí)例分析
    • [JVM]理解Class文件(1):手動(dòng)解析常量池
    • [JVM]理解GC日志
    • [JVM]理解Class文件(2)

1. 輸出GC日志

通過閱讀GC日志,我們可以了解Java虛擬機(jī)內(nèi)存分配與回收策略
先來看一個(gè)簡單的示例,通過設(shè)置VM參數(shù)"XX:+PrintGCDetails"就可以打印出GC日志

zhanghuamaodeMacBook-Pro:java zhanghuamao$ java -XX:+PrintGCDetails TestClass hello HeapPSYoungGen total 76288K, used 3932K [0x000000076ab00000, 0x0000000770000000, 0x00000007c0000000)eden space 65536K, 6% used [0x000000076ab00000,0x000000076aed7240,0x000000076eb00000)from space 10752K, 0% used [0x000000076f580000,0x000000076f580000,0x0000000770000000)to space 10752K, 0% used [0x000000076eb00000,0x000000076eb00000,0x000000076f580000)ParOldGen total 175104K, used 0K [0x00000006c0000000, 0x00000006cab00000, 0x000000076ab00000)object space 175104K, 0% used [0x00000006c0000000,0x00000006c0000000,0x00000006cab00000)Metaspace used 2630K, capacity 4486K, committed 4864K, reserved 1056768Kclass space used 286K, capacity 386K, committed 512K, reserved 1048576K
  • PSYoungGen
    PS是Parallel Scavenge收集器的縮寫,它配套的新生代稱為PSYoungGen,新生代又分化eden space、from space和to space這三部分

  • ** ParOldGen**
    Parallel Scavenge收集器配套的老年代

  • Metaspace
    Parallel Scavenge收集器配套的永久代

  • total & used
    總的空間和用掉的空間

2. GC日志分析

2.1 新生代Minor GC

先來回顧下垃圾回收算法,通常新生代按照8:1:1(eden space + survivor from space + survivor to space)進(jìn)行內(nèi)存劃分,新生產(chǎn)的對(duì)象會(huì)被放到eden space,當(dāng)eden內(nèi)存不足時(shí),就會(huì)將存活對(duì)象移動(dòng)到survivor區(qū)域,如果survivor空間也不夠時(shí),就需要從老年代中進(jìn)行分配擔(dān)保,將存活的對(duì)象移動(dòng)老年代,這就是一次Minor GC的過程。

新生代

1. 示例代碼

  • code
/*** VM agrs: -verbose:gc -Xms20M -Xmx20M -Xmn10M -XX:+PrintGCDetails* -XX:SurvivorRatio=8 -XX:+UseSerialGC*/public class MinorGCTest {private static final int _1MB = 1024 * 1024;public static void testAllocation() {byte[] allocation1, allocation2, allocation3, allocation4;allocation1 = new byte[2 * _1MB];allocation2 = new byte[2 * _1MB];allocation3 = new byte[2 * _1MB];allocation4 = new byte[4 * _1MB];}public static void main(String[] agrs) {testAllocation();} }
  • VM參數(shù)說明
OptionDescription
-verbose:gc顯示GC的操作內(nèi)容
-Xms20M -Xmx20M設(shè)置堆大小為20M
-Xmn10M設(shè)置新生代的內(nèi)存空間大小為10M
-XX:+PrintGCDetails打印GC中的變化
-XX:SurvivorRatio=8新生代中Eden區(qū)域與Survivor區(qū)域的大小比值
-XX:+UseSerialGC在新生代和老年代中使用串行收集器,由于-verbose:gc參數(shù)對(duì)Parallel Scavenge收集器不起作用,無法顯示顯示GC的操作內(nèi)容,因此采用串行收集器
  • 示例代碼說明
  • 該段代碼一共創(chuàng)建了4個(gè)數(shù)組對(duì)象,在給allocation4分配空間前的內(nèi)存空間使用情況如下:

?

before MinorGC

  • 需要執(zhí)行一次MinorGC才能給allocation4分配空間,分配成功以后內(nèi)存空間使用情況如下:

?

after MinorGC

2. GC日志

?

Minor GC日志

  • [GC [DefNew ... ...]

  • GC日志開頭的信息通過設(shè)置-verbose:gc參數(shù)后才能輸出。

  • "[GC""[Full GC"說明這次垃圾收集的停頓類型,如果這次GC發(fā)生了Stop-The-World,則為"[Full GC",否則為"[GC"

  • "[DefNew "表示GC發(fā)生的區(qū)域?yàn)镾erial收集器的新生代中,DefNew是"Default New Generation"的縮寫。Serial收集器的老年代和永久代分別表示為"Tenured""Perm"

  • ** eden space 8192K, 52% used**

  • 新生代的Eden區(qū)總共大小為8MB,使用掉的4MB是用來存放allocation4對(duì)象

  • tenured generation total 10240K, used 6144K

  • 老年代大小為10MB,使用掉的6MB是用來存放allocation1、allocation2和allocation3這3個(gè)對(duì)象

2.2 大對(duì)象直接進(jìn)入老年代

1. 示例代碼

  • code
/*** VM agrs: -verbose:gc -Xms20M -Xmx20M -Xmn10M -XX:+PrintGCDetails* -XX:SurvivorRatio=8 -XX:+UseSerialGC * -XX:PretenureSizeThreshold=3145728*/public class TestClass2 {private static final int _1MB = 1024 * 1024;public static void testPretenureSizeThreshold() {byte[] allocation;allocation = new byte[4 * _1MB];}/*** @param args*/public static void main(String[] args) {// TODO Auto-generated method stubtestPretenureSizeThreshold();}}
  • VM參數(shù)說明
OptionDescription
-XX:PretenureSizeThreshold=3145728所占用內(nèi)存大于該值的對(duì)象直接分配到老年代,3145728為3MB
  • 示例代碼說明
    該段代碼創(chuàng)建了一個(gè)數(shù)組對(duì)象allocation,大小為4MB,已經(jīng)超出PretenureSizeThreshold設(shè)置的范圍,該對(duì)象將直接被分配到老年代中。

2. GC日志

大對(duì)象直接進(jìn)入老年代-GC日志

  • tenured generation total 10240K, used 4096K
    老年代大小為10MB,用掉的4MB用來存放allocation對(duì)象

2.3 長期存活的對(duì)象進(jìn)入老年代

1. 示例代碼

  • code
/*** VM agrs: -verbose:gc -Xms20M -Xmx20M -Xmn10M -XX:+PrintGCDetails* -XX:SurvivorRatio=8 -XX:+UseSerialGC -XX:MaxTenuringThreshold=1*/public class TestClass3 {private static final int _1MB = 1024 * 1024;public static void testTenuringThreshold() {byte[] allocation1, allocation2, allocation3;allocation1 = new byte[_1MB / 4];allocation2 = new byte[4 * _1MB];allocation3 = new byte[4 * _1MB];allocation3 = null;allocation3 = new byte[4 * _1MB];}public static void main(String[] agrs) {testTenuringThreshold();} }
  • VM參數(shù)說明
OptionDescription
-XX:MaxTenuringThreshold=1對(duì)象晉升為老年代的年齡閥值為1
  • 示例代碼說明
    該段代碼創(chuàng)建了3個(gè)數(shù)組對(duì)象,當(dāng)執(zhí)行到"allocation3 = new byte[4 * _1MB]; "時(shí),Eden已經(jīng)被占用了256KB + 4MB,而創(chuàng)建allocation3需要4MB,已經(jīng)超過Eden的大小8MB,需要先發(fā)生一次MinorGC,才能保證有空間存放allocation3

2. GC日志

  • 設(shè)置參數(shù)為MaxTenuringThreshold=1的運(yùn)行結(jié)果

  • 由GC日志開頭的兩句"[GC [DefNew"可知,該段代碼一共發(fā)生了2次GC,第一次是"allocation3 = new byte[4 * _1MB]; ",第二次是執(zhí)行allocation3 = null時(shí)

  • allocation1在經(jīng)過第一次GC時(shí),對(duì)象年齡變成了1,由于設(shè)置的MaxTenuringThreshold=1,當(dāng)發(fā)生第二次GC時(shí),allocation1的年齡已經(jīng)超出了設(shè)置的閥值,allocation1進(jìn)入到老年代,因此,新生代的from space使用空間為0,對(duì)應(yīng)GC語句為from space 1024K, 0% used

?

MaxTenuringThreshold=1

  • 設(shè)置參數(shù)為MaxTenuringThreshold=15的運(yùn)行結(jié)果
    由于設(shè)置的MaxTenuringThreshold=15,發(fā)生第二次GC時(shí),allocation1的年齡沒有超出設(shè)置的閥值,因此,新生代的from space使用空間不為0,對(duì)應(yīng)GC語句為from space 1024K, 44% used

?

MaxTenuringThreshold=15

3. 參考

  • 深入理解Java虛擬機(jī):JVM高級(jí)特性與最佳實(shí)踐(第2版)

總結(jié)

以上是生活随笔為你收集整理的JVM:GC日志解读的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網(wǎng)站內(nèi)容還不錯(cuò),歡迎將生活随笔推薦給好友。