1. 程式人生 > >jvm系列(九):Java GC 分析

jvm系列(九):Java GC 分析

Java GC就是JVM記錄儀,書畫了JVM各個分割槽的表演。

什麼是 Java GC

Java GC(Garbage Collection,垃圾收集,垃圾回收)機制,是Java與C++/C的主要區別之一,作為Java開發者,一般不需要專門編寫記憶體回收和垃圾清理程式碼,對記憶體洩露和溢位的問題,也不需要像C程式設計師那樣戰戰兢兢。這是因為在Java虛擬機器中,存在自動記憶體管理和垃圾清掃機制。概括地說,該機制對JVM(Java Virtual Machine)中的記憶體進行標記,並確定哪些記憶體需要回收,根據一定的回收策略,自動的回收記憶體,永不停息(Nerver Stop)的保證JVM中的記憶體空間,防止出現記憶體洩露和溢位問題。

在Java語言出現之前,就有GC機制的存在,如Lisp語言),Java GC機制已經日臻完善,幾乎可以自動的為我們做絕大多數的事情。然而,如果我們從事較大型的應用軟體開發,曾經出現過記憶體優化的需求,就必定要研究Java GC機制。

簡單總結一下,Java GC就是通過GC收集器回收不在存活的物件,保證JVM更加高效的運轉。如果不瞭解GC演算法和垃圾回收器可以參考這篇文章:jvm系列(三):GC演算法 垃圾收集器

如何獲取 Java GC日誌

一般情況可以通過兩種方式來獲取GC日誌,一種是使用命令動態檢視,一種是在容器中設定相關引數列印GC日誌。

命令動態檢視

Java 自動的工具行命令,jstat可以用來動態監控JVM記憶體的使用,統計垃圾回收的各項資訊。

比如常用命令,jstat -gc 統計垃圾回收堆的行為

$ jstat -gc 1262
 S0C    S1C     S0U     S1U   EC       EU        OC         OU        PC       PU         YGC    YGCT    FGC    FGCT     GCT   
26112.0 24064.0 6562.5  0.0   564224.0 76274.5   434176.0   388518.3  524288.0 42724.7    320    6.417   1      0.398    6.815

也可以設定間隔固定時間來列印:

$ jstat -gc 1262 2000 20

這個命令意思就是每隔2000ms輸出1262的gc情況,一共輸出20次

GC引數

JVM的GC日誌的主要引數包括如下幾個:

  • -XX:+PrintGC 輸出GC日誌
  • -XX:+PrintGCDetails 輸出GC的詳細日誌
  • -XX:+PrintGCTimeStamps 輸出GC的時間戳(以基準時間的形式)
  • -XX:+PrintGCDateStamps 輸出GC的時間戳(以日期的形式,如 2017-09-04T21:53:59.234+0800)
  • -XX:+PrintHeapAtGC 在進行GC的前後打印出堆的資訊
  • -Xloggc:../logs/gc.log 日誌檔案的輸出路徑

在生產環境中,根據需要配置相應的引數來監控JVM執行情況。

Tomcat 設定示例

我們經常在tomcat的啟動引數中新增JVM相關引數,這裡有一個典型的示例:

JAVA_OPTS="-server -Xms2000m -Xmx2000m -Xmn800m -XX:PermSize=64m -XX:MaxPermSize=256m -XX:SurvivorRatio=4-verbose:gc -Xloggc:$CATALINA_HOME/logs/gc.log -Djava.awt.headless=true -XX:+PrintGCTimeStamps -XX:+PrintGCDetails -Dsun.rmi.dgc.server.gcInterval=600000 -Dsun.rmi.dgc.client.gcInterval=600000-XX:+UseConcMarkSweepGC -XX:MaxTenuringThreshold=15"

根據上面的引數我們來做一下解析:

  • -Xms2000m -Xmx2000m -Xmn800m -XX:PermSize=64m -XX:MaxPermSize=256m
    Xms,即為jvm啟動時得JVM初始堆大小,Xmx為jvm的最大堆大小,xmn為新生代的大小,permsize為永久代的初始大小,MaxPermSize為永久代的最大空間。

  • -XX:SurvivorRatio=4
    SurvivorRatio為新生代空間中的Eden區和救助空間Survivor區的大小比值,預設是8,則兩個Survivor區與一個Eden區的比值為2:8,一個Survivor區佔整個年輕代的1/10。調小這個引數將增大survivor區,讓物件儘量在survitor區呆長一點,減少進入年老代的物件。去掉救助空間的想法是讓大部分不能馬上回收的資料儘快進入年老代,加快年老代的回收頻率,減少年老代暴漲的可能性,這個是通過將-XX:SurvivorRatio 設定成比較大的值(比如65536)來做到。

  • -verbose:gc -Xloggc:$CATALINA_HOME/logs/gc.log
    將虛擬機器每次垃圾回收的資訊寫到日誌檔案中,檔名由file指定,檔案格式是平檔案,內容和-verbose:gc輸出內容相同。

  • -Djava.awt.headless=true
    Headless模式是系統的一種配置模式。在該模式下,系統缺少了顯示裝置、鍵盤或滑鼠。

  • -XX:+PrintGCTimeStamps -XX:+PrintGCDetails
    設定gc日誌的格式

  • -Dsun.rmi.dgc.server.gcInterval=600000 -Dsun.rmi.dgc.client.gcInterval=600000
    指定rmi呼叫時gc的時間間隔

  • -XX:+UseConcMarkSweepGC -XX:MaxTenuringThreshold=15
    採用併發gc方式,經過15次minor gc 後進入年老代

如何分析GC日誌

摘錄GC日誌一部分

Young GC回收日誌:

2016-07-05T10:43:18.093+0800: 25.395: [GC [PSYoungGen: 274931K->10738K(274944K)] 371093K->147186K(450048K), 0.0668480 secs] [Times: user=0.17 sys=0.08, real=0.07 secs]

Full GC回收日誌:

2016-07-05T10:43:18.160+0800: 25.462: [Full GC [PSYoungGen: 10738K->0K(274944K)] [ParOldGen: 136447K->140379K(302592K)] 147186K->140379K(577536K) [PSPermGen: 85411K->85376K(171008K)], 0.6763541 secs] [Times: user=1.75 sys=0.02, real=0.68 secs]

通過上面日誌分析得出,PSYoungGen、ParOldGen、PSPermGen屬於Parallel收集器。其中PSYoungGen表示gc回收前後年輕代的記憶體變化;ParOldGen表示gc回收前後老年代的記憶體變化;PSPermGen表示gc回收前後永久區的記憶體變化。young gc 主要是針對年輕代進行記憶體回收比較頻繁,耗時短;full gc 會對整個堆記憶體進行回城,耗時長,因此一般儘量減少full gc的次數

通過兩張圖非常明顯看出gc日誌構成:

Young GC日誌:

Full GC日誌:

GC分析工具

GChisto

GChisto是一款專業分析gc日誌的工具,可以通過gc日誌來分析:Minor GC、full gc的時間、頻率等等,通過列表、報表、圖表等不同的形式來反應gc的情況。雖然介面略顯粗糙,但是功能還是不錯的。

配置好本地的jdk環境之後,雙擊GChisto.jar,在彈出的輸入框中點選 add 選擇gc.log日誌

  • GC Pause Stats:可以檢視GC 的次數、GC的時間、GC的開銷、最大GC時間和最小GC時間等,以及相應的柱狀圖
  • GC Pause Distribution:檢視GC停頓的詳細分佈,x軸表示垃圾收集停頓時間,y軸表示是停頓次數。

  • GC Timeline:顯示整個時間線上的垃圾收集

不過這款工具已經不再維護

GC Easy

這是一個web工具,線上使用非常方便.

進入官網,講打包好的zip或者gz為字尾的壓縮包上傳,過一會就會拿到分析結果。

推薦使用此工具進行gc分析。

相關推薦

jvm系列():Java GC 分析

Java GC就是JVM記錄儀,書畫了JVM各個分割槽的表演。 什麼是 Java GC Java GC(Garbage Collection,垃圾收集,垃圾回收)機制,是Java與C++/C的主要區別之一,作為Java開發者,一般不需要專門編寫記憶體回收和垃圾清理程式碼,對記憶體洩露和溢位的問題,也

[jvm]java gc分析

Java GC就是JVM記錄儀,書畫了JVM各個分割槽的表演。 什麼是 Java GC Java GC(Garbage Collection,垃圾收集,垃圾回收)機制,是Java與C++/C的主要區別之一,作為Java開發者,一般不需要專門編寫記憶體回收和垃圾清理程式碼,對記憶體洩露和溢

jvm系列(三):java GC算法 垃圾收集器

應對 sca 互聯 都是 生命 改進 壓縮 速度 垃圾收集器 原文鏈接:http://www.cnblogs.com/ityouknow/p/5614961.html 概述 垃圾收集 Garbage Collection 通常被稱為“GC”,它誕生於1960年 MIT 的

jvm系列(三):java GC演算法 垃圾收集器

GC演算法 垃圾收集器 概述 垃圾收集 Garbage Collection 通常被稱為“GC”,它誕生於1960年 MIT 的 Lisp 語言,經過半個多世紀,目前已經十分成熟了。 jvm 中,程式計數器、虛擬機器棧、本地方法棧都是隨執行緒而生隨執行緒而滅,棧幀隨著方法的進入和退出做入棧和出棧

jvm系列:Java GC 分析

maxperm 日期 格式 ogg nth 意思 his cat 比較 Java GC就是JVM記錄儀,書畫了JVM各個分區的表演。 什麽是 Java GC Java GC(Garbage Collection,垃圾收集,垃圾回收)機制,是Java與C++/C的主要區別

jvm系列(六):Java服務GC引數調優案例

本文介紹了一次生產環境的JVM GC相關引數的調優過程,通過引數的調整避免了GC卡頓對JAVA服務成功率的影響。 這段時間在整理jvm系列的文章,無意中發現本文,作者思路清晰通過步步分析最終解決問題。我個人特別喜歡這種實戰類的內容,經原作者的授權同意,將文章分

Java GC 分析JVM生產環境引數例項及分析JVM詳細配置

什麼是 Java GC Java GC(Garbage Collection,垃圾收集,垃圾回收)機制,是Java與C++/C的主要區別之一,作為Java開發者,一般不需要專門編寫記憶體回收和垃圾清理程式碼,對記憶體洩露和溢位的問題,也不需要像C程式設計師那樣戰戰兢兢。這是

jvm系列(一):java類的加載機制

java語言 javac 字段 元素 對象實例 length 構造函數 class not 類加載機制的奧妙。 1、什麽是類的加載 類的加載指的是將類的.class文件中的二進制數據讀入到內存中,將其放在運行時數據區的方法區內,然後在堆區創建一個java.lang.Clas

jvm系列(一):java類的載入機制

1、什麼是類的載入 類的載入指的是將類的.class檔案中的二進位制資料讀入到記憶體中,將其放在執行時資料區的方法區內,然後在堆區建立一個java.lang.Class物件,用來封裝類在方法區內的資料結構。類的載入的最終產品是位於堆區中的Class物件,Clas

1.JVM原理、java記憶體分析

目錄 JVM原理 記憶體分析 共享 獨有 JVM原理 JVM生命週期:一個執行中的Java虛擬機器有著一個清晰的任務:執行Java程式。你在同一臺機器上執行三個程式,就會有三個執行中的Java虛擬機器。 Main()方法是程式的起點,程式中其他的

JVM基礎系列教程|第四篇:Java GC 日誌分析

推薦視訊連結 什麼是 Java GC Java GC(Garbage Collection,垃圾收集,垃圾回收)機制,是Java與C++/C的主要區別之一,作為Java開發者,一般不需要專門編寫記憶體回收和垃圾清理程式碼,對記憶體洩露和溢位的問題,也不需要像

JVM系列GC引數分析和調優

不管是YGC還是Full GC,GC過程中都會對導致程式執行中中斷,正確的選擇不同的GC策略,調整JVM、GC的引數,可以極大的減少由於GC工作,而導致的程式執行中斷方面的問題,進而適當的提高Java程式的工作效率。但是調整GC是以個極為複雜的過程,由於各個程式具備不同的特點

jvm系列(十):如何優化Java GC「譯」

Sangmin Lee發表在Cubrid上的"Become a Java GC Expert"系列文章的第三篇《How to Tune Java Garbage Collection》,本文的作者是韓國人,寫在JDK 1.8釋出之前,雖然有些地方有些許過時,但整體內容還是

JVM系列文章(一):Java記憶體區域分析

所有內容均參考自《深入理解Java虛擬機器:JVM高階特性與最佳實踐》(第二版),感謝作者。 本文是系列文章第一篇,講述的是Java記憶體區域,即在虛擬機器上,資料是怎麼儲存的。 一、執行時資料區域 執行時資料區分為兩個部分,一部分由所有執行緒共享,一部分是各個執行緒

JVM系列【6】GC與調優5-日誌分析

### JVM系列筆記目錄 > - 虛擬機器的基礎概念 > - class檔案結構 > - class檔案載入過程 > - jvm記憶體模型 > - JVM常用指令 > - GC與調優 #### 主要內容 分析PS、CMS、G1的回收日誌,目標使大概能讀懂GC日誌

jvm系列學習之--Java的類加載機制

任務 字節 修飾符 https 完整 自定義類加載器 字節流 由於 字節碼 轉載:https://segmentfault.com/a/1190000004597758 本文主要講述Java類的加載機制,主要包括類加載器、加載過程、初始化時機。 一、類加載器 1、Clas

jvm系列學習之--Java類的初始化順序

parent main方法 println () 類成員 -- sys div 開始 本文主要演示Java類的初始化順序 初始化順序 對於靜態變量、靜態初始化塊、變量、初始化塊、構造器,它們的初始化順序依次是(靜態變量、靜態初始化塊)>(變量、初始化塊)>構造器

JVM系列三:JVM參數設置、分析

文檔 將在 執行 weblogic adapt min new t timestamp 大內存 JVM系列三:JVM參數設置、分析 不管是YGC還是F

(拿來主義-4) JVM系列(四) - JVM GC回收算法

年輕代和老年代 變量 jdk major gc 高效 image 隊列 you 頻率 JVM系列(四) - JVM GC回收算法 轉載自https://juejin.im/post/5b4dea755188251ac1098e98 前言 第二篇介紹了Java內存運行時區域

性能測試系列-java gc調優

操作 發生 失敗 應用 目標 社區 為什麽 不知道 current 性能測試中除了需要做好性能測試外,我們還需要做性能測試後的,性能調優,需要發現性能問題,也需要做性能調優,在做性能調優中,jvm的性能調優是經常遇到的一個。 隨著jdk版本的迅速變化,jdk裏面的GC算法也