成人免费xxxxx在线视频软件_久久精品久久久_亚洲国产精品久久久_天天色天天色_亚洲人成一区_欧美一级欧美三级在线观看

三分鐘帶你看懂 GC 日志!

開發 前端
在 jdk1.8 及之后的版本中,-XX:+UseParallelGC和-XX:+UseParallelOldGC?參數效果是一樣的,都是用的 Parallel Old 作為老年代收集器;而在 jdk1.7 及之后的版本中,-XX:+UseParallelGC參數用的是 Serial Old 作為老年代收集器。

01、背景介紹

那么如何分析當前虛擬機性能呢?其中 GC 日志起到至關重要的作用。

實際上,每種垃圾收集器都有它獨立的日志格式,盡管如此,虛擬機為了方便用戶閱讀,將各個收集器的日志都維持在一定的共性狀態。

下面我們一起來看看不同的垃圾收集器,相關的 GC 日志內容。

本文是基于 JDK 1.8 版本運行,可能不同的版本各個內存區域的名稱略有不同,對知識的理解不會產生明顯的誤區。

02、觸發GC時機

通常,GC 觸發的條件有兩種:

1.程序調用System.gc時可能會觸發,此時會建議 JVM 進行垃圾回收,但不代表一定會進行 GC 動作;

2.系統自身來決定 GC 觸發的時機,比如年輕代空間不足、老年代空間不足等就會主動觸發 GC 動作

以上兩種行為都會產生 GC 日志。

03、GC日志

在介紹之前,我們先看一段代碼,下文的 GC 日志都會基于這段代碼來分析。

/**
 * 虛擬機參數:-verbose:gc
 */
public class GCObjectTest {

    public Object instance = null;

    /**
     * 設置成員屬性占用一點內存,2M
     */
    public byte[] bigSize = new byte[2 * 1024 * 1024];

    public static void main(String[] args) {
        GCObjectTest objectA = new GCObjectTest();
        GCObjectTest objectB = new GCObjectTest();

        // 設置兩個對象互相引用
        objectA.instance = objectB;
        objectB.instance = objectA;

        objectB = null;
        objectA = null;

        // 觸發 GC,不一定實時生效
        System.gc();

    }
}

運行時加上-verbose:gc參數,以便簡要的查看程序的 GC 情況,運行后的輸出結果如下!

[GC (System.gc())  6101K->520K(125952K), 0.0022878 secs]
[Full GC (System.gc())  520K->408K(125952K), 0.0049120 secs]

以上代碼是一段對象相互引用的場景,但是 JVM 還是將對象回收了,也應證了一點,HotSpot 虛擬機并不是通過引用計數法來判定對象是否存活的。

下面我們還是以上面的代碼為例,設置不同的虛擬機參數,看看 GC 日志情況。

3.1、Serial 和 Serial Old 組合垃圾收集器

Serial 和 Serial Old 組合的垃圾收集器,可以在運行時設置如下參數來開啟。

-XX:+PrintGCDetails
-XX:+UseSerialGC

運行之后,輸出結果如下!

[Full GC (System.gc()) [Tenured: 0K->393K(87424K), 0.0104804 secs] 6891K->393K(126720K), [Metaspace: 3052K->3052K(1056768K)], 0.0105689 secs] [Times: user=0.00 sys=0.00, real=0.01 secs] 
Heap
 def new generation   total 39424K, used 351K [0x0000000740000000, 0x0000000742ac0000, 0x000000076aaa0000)
  eden space 35072K,   1% used [0x0000000740000000, 0x0000000740057c58, 0x0000000742240000)
  from space 4352K,   0% used [0x0000000742240000, 0x0000000742240000, 0x0000000742680000)
  to   space 4352K,   0% used [0x0000000742680000, 0x0000000742680000, 0x0000000742ac0000)
 tenured generation   total 87424K, used 393K [0x000000076aaa0000, 0x0000000770000000, 0x00000007c0000000)
   the space 87424K,   0% used [0x000000076aaa0000, 0x000000076ab02608, 0x000000076ab02800, 0x0000000770000000)
 Metaspace       used 3062K, capacity 4496K, committed 4864K, reserved 1056768K
  class space    used 336K, capacity 388K, committed 512K, reserved 1048576K

各個參數描述介紹:

  • def new generation:表示年輕代的內存使用情況,其中eden space表示Eden空間的內存使用情況;from space表示From Survivor空間的內存使用情況;to space表示To Survivor空間的內存使用情況;
  • tenured generation:表示老年代的內存使用情況
  • Metaspace:表示元空間的內存使用情況,在 JDK1.7 中稱為永久代

3.2、ParNew 和 Serial Old 組合垃圾收集器

ParNew 和 Serial Old 組合的垃圾收集器,可以在運行時設置如下參數來開啟。

-XX:+PrintGCDetails
-XX:+UseParNewGC

運行之后,輸出結果如下!

[Full GC (System.gc()) [Tenured: 0K->395K(87424K), 0.0044216 secs] 6891K->395K(126720K), [Metaspace: 3058K->3058K(1056768K)], 0.0044869 secs] [Times: user=0.01 sys=0.01, real=0.00 secs] 
Heap
 par new generation   total 39424K, used 1052K [0x0000000740000000, 0x0000000742ac0000, 0x000000076aaa0000)
  eden space 35072K,   3% used [0x0000000740000000, 0x0000000740107228, 0x0000000742240000)
  from space 4352K,   0% used [0x0000000742240000, 0x0000000742240000, 0x0000000742680000)
  to   space 4352K,   0% used [0x0000000742680000, 0x0000000742680000, 0x0000000742ac0000)
 tenured generation   total 87424K, used 395K [0x000000076aaa0000, 0x0000000770000000, 0x00000007c0000000)
   the space 87424K,   0% used [0x000000076aaa0000, 0x000000076ab02d70, 0x000000076ab02e00, 0x0000000770000000)
 Metaspace       used 3064K, capacity 4496K, committed 4864K, reserved 1056768K
  class space    used 336K, capacity 388K, committed 512K, reserved 1048576K

其中par new generation表示年輕代的內存使用情況,其它表達的內容與上相同。

3.3、Parallel Scavenge 和 Parallel Old 組合垃圾收集器

Parallel Scavenge 和 Parallel Old 組合的垃圾收集器,可以在運行時設置如下參數來開啟。

-XX:+PrintGCDetails
-XX:+UseParallelOldGC

需要注意的是,在 jdk1.8 及之后的版本中,-XX:+UseParallelGC和-XX:+UseParallelOldGC參數效果是一樣的,都是用的 Parallel Old 作為老年代收集器;而在 jdk1.7 及之后的版本中,-XX:+UseParallelGC參數用的是 Serial Old 作為老年代收集器。

運行之后,輸出結果如下!

[GC (System.gc()) [PSYoungGen: 6767K->496K(38400K)] 6767K->504K(125952K), 0.0014375 secs] [Times: user=0.00 sys=0.00, real=0.00 secs] 
[Full GC (System.gc()) [PSYoungGen: 496K->0K(38400K)] [ParOldGen: 8K->390K(87552K)] 504K->390K(125952K), [Metaspace: 3008K->3008K(1056768K)], 0.0045268 secs] [Times: user=0.01 sys=0.00, real=0.00 secs] 
Heap
 PSYoungGen      total 38400K, used 998K [0x0000000795580000, 0x0000000798000000, 0x00000007c0000000)
  eden space 33280K, 3% used [0x0000000795580000,0x0000000795679b20,0x0000000797600000)
  from space 5120K, 0% used [0x0000000797600000,0x0000000797600000,0x0000000797b00000)
  to   space 5120K, 0% used [0x0000000797b00000,0x0000000797b00000,0x0000000798000000)
 ParOldGen       total 87552K, used 390K [0x0000000740000000, 0x0000000745580000, 0x0000000795580000)
  object space 87552K, 0% used [0x0000000740000000,0x0000000740061b10,0x0000000745580000)
 Metaspace       used 3042K, capacity 4496K, committed 4864K, reserved 1056768K
  class space    used 333K, capacity 388K, committed 512K, reserved 1048576K

其中PSYoungGen表示年輕代的內存使用情況;ParOldGen表示老年代的內存使用情況,其它表達的內容與上相同。

3.4、ParNew 和 CMS + Serial Old 組合垃圾收集器

ParNew 和 CMS + Serial Old 組合的垃圾收集器,可以在運行時設置如下參數來開啟。

-XX:+PrintGCDetails
-XX:+UseConcMarkSweepGC

運行之后,輸出結果如下!

[Full GC (System.gc()) [CMS: 0K->388K(87424K), 0.0214068 secs] 6192K->388K(126720K), [Metaspace: 2925K->2925K(1056768K)], 0.0214982 secs] [Times: user=0.01 sys=0.01, real=0.03 secs] 
Heap
 par new generation   total 39424K, used 1052K [0x0000000740000000, 0x0000000742ac0000, 0x0000000754cc0000)
  eden space 35072K,   3% used [0x0000000740000000, 0x0000000740107280, 0x0000000742240000)
  from space 4352K,   0% used [0x0000000742240000, 0x0000000742240000, 0x0000000742680000)
  to   space 4352K,   0% used [0x0000000742680000, 0x0000000742680000, 0x0000000742ac0000)
 concurrent mark-sweep generation total 87424K, used 388K [0x0000000754cc0000, 0x000000075a220000, 0x00000007c0000000)
 Metaspace       used 2932K, capacity 4496K, committed 4864K, reserved 1056768K
  class space    used 319K, capacity 388K, committed 512K, reserved 1048576K

其中par new generation表示年輕代的內存使用情況;concurrent mark-sweep generation表示老年代的內存使用情況,其它表達的內容與上相同。

3.5、G1 垃圾收集器

G1 垃圾收集器,可以在運行時設置如下參數來開啟。

-XX:+PrintGCDetails
-XX:+UseG1GC

運行之后,輸出結果如下!

[Full GC (System.gc())  5985K->395K(8192K), 0.0083534 secs]
   [Eden: 2048.0K(14.0M)->0.0B(4096.0K) Survivors: 0.0B->0.0B Heap: 5985.1K(128.0M)->395.9K(8192.0K)], [Metaspace: 3059K->3059K(1056768K)]
 [Times: user=0.01 sys=0.00, real=0.01 secs] 
Heap
 garbage-first heap   total 8192K, used 395K [0x0000000740000000, 0x0000000740100040, 0x00000007c0000000)
  region size 1024K, 1 young (1024K), 0 survivors (0K)
 Metaspace       used 3066K, capacity 4496K, committed 4864K, reserved 1056768K
  class space    used 336K, capacity 388K, committed 512K, reserved 1048576K

G1 收集器與以上收集器都不同,它會把整個 Java 堆分成若干個大小相等的獨立區域,也是日志中的 Region,然后針對優先級高的 Region 區域進行收集。Region 區域可能存放的是年輕代的對象,也可能是老年代的對象。

04、小結

以上的日志輸出,會發現很多的共性。

比如,以“GC”開頭的,通常表示年輕代的收集情況;以“Full GC”開頭的,表示整個堆的收集情況,其中帶有“(System.gc()) ”信息的表示調用System.gc()方法所觸發的 GC。

以下面這個日志為例,來解讀一下相關信息。

[Full GC (System.gc()) [PSYoungGen: 496K->0K(38400K)] [ParOldGen: 8K->390K(87552K)] 504K->390K(125952K), [Metaspace: 3008K->3008K(1056768K)], 0.0045268 secs] [Times: user=0.01 sys=0.00, real=0.00 secs]

1.Full GC (System.gc()表示 Full GC 類型的 GC 動作,通過調用System.gc()方法而觸發;

2.PSYoungGen: 496K->0K(38400K)表示年輕代 GC 前使用的容量為 496K,GC 后該內存區域使用的容量為 0K,年輕代總容量為 38400K;

3.ParOldGen: 8K->390K(87552K)表示老年代 GC 前使用的容量為 8K,GC 后該內存區域使用的容量為 390K,老年代總容量為 87552K;

4.504K->390K(125952K)表示整個堆 GC 前使用的容量為 504K,GC 后該內存區域使用的容量為 390K,整個堆總容量為 125952K;

5.Metaspace: 3008K->3008K(1056768K)表示元空間 GC 前使用的容量為 3008K,GC 后該內存區域使用的容量為 3008K,整個元空間總容量為 1056768K;

6.0.0045268 secs表示 Full GC 耗時為 0.0045268 秒;

7.Times: user=0.01 sys=0.00, real=0.00 secs表示 Full GC 期間用戶的耗時、系統的耗時、實際操作的耗時,單位秒;

Heap 后面列舉的是堆的內存使用情況。

責任編輯:武曉燕 來源: 潘志的研發筆記
相關推薦

2021-04-20 13:59:37

云計算

2020-06-30 10:45:28

Web開發工具

2022-02-17 09:24:11

TypeScript編程語言javaScrip

2024-01-16 07:46:14

FutureTask接口用法

2022-02-24 10:28:23

物聯網

2020-06-29 07:42:20

邊緣計算云計算技術

2024-01-12 07:38:38

AQS原理JUC

2021-02-03 14:31:53

人工智能人臉識別

2024-07-05 09:31:37

2017-01-18 15:38:20

語言

2024-09-13 08:49:45

2020-03-08 16:45:58

數據挖掘學習數據量

2020-08-17 17:20:36

pythonJAVA代碼

2024-02-22 07:37:37

對象JVM內存

2024-06-06 08:50:43

2024-05-16 11:13:16

Helm工具release

2009-11-09 12:55:43

WCF事務

2024-12-18 10:24:59

代理技術JDK動態代理

2022-02-21 18:16:38

Go語言枚舉

2019-03-28 08:39:47

5GNSASA
點贊
收藏

51CTO技術棧公眾號

主站蜘蛛池模板: 精品国产一区二区三区免费 | 成人精品一区二区三区中文字幕 | 国产成人精品一区二区 | 欧洲免费毛片 | 国产精品久久久久久久久久软件 | 亚洲精品99999 | 中文字幕免费视频 | 久久黄色网 | 国产精品爱久久久久久久 | 国产视频福利 | 极品在线 | 欧美一区二区三区免费电影 | 一级毛片免费 | 成人av鲁丝片一区二区小说 | 国产中文在线 | 女人牲交视频一级毛片 | 波霸ol一区二区 | 天天干,夜夜操 | 国产在线一区二区三区 | 日韩一区二区在线视频 | 久久噜噜噜精品国产亚洲综合 | 日韩中文字幕在线视频 | 国产1区| 成人av一区二区亚洲精 | 欧美激情亚洲激情 | 日本高清aⅴ毛片免费 | 男女爱爱福利视频 | 91麻豆精品国产91久久久久久 | 日韩三级视频 | 黄网免费看 | 亚洲精品1区2区3区 91免费看片 | 欧美成人一级 | 亚洲成人一区二区三区 | 在线视频亚洲 | 亚洲a视频 | 欧美日韩国产一区二区三区 | 成人精品一区 | 毛片一级片 | 精品一区二区三区视频在线观看 | 久色一区 | 欧美一区二区三区小说 |