《JVM故障診斷指南》之1 —— JVM概覽與介紹
Oracle HotSpot JVM 內存
Java HotSpot 虛擬機堆空間
這個部分將向你介紹Oracle Java HotSpot虛擬機裏不同的Java堆內存空間概覽。理解這個對於任何一個涉及到線上經常出現的內存問題的解決非常重要。而具有合適的Java 虛擬機堆空間的知識是很關鍵的。
Java虛擬機是你Java程序的基礎,它提供了動態內存管理服務,垃圾收集,線程,IO以及本地操作等等。
Java堆空間是運行時Java程序的內存“容器”,它為你的Java程序提供了它需要的(Java堆,本地堆)合適的內存空間,並由JVM自身管理。
JVM HotSpot內存被分為3個內存空間:
• The Java Heap(堆)
• The PermGen (持久代)
• 本地堆(C-堆)
下麵是他們的詳細分類:
內存空間 | 啟動參數和調整方法 | 監控方式 | 描述 |
---|---|---|---|
Java 堆 | -Xmx (最大堆容量) -Xms (最小堆容量) |
EX:
-Xmx1024m
-Xms1024m-verbose GC
– JMX API
– JConsole
– 其他監控工具Java堆是存儲你的主要
的Java程序Class實例。持久代-XX:MaxPermSize (最大容量)
-XX:PermSize (最小容量)
EX:
-XX:MaxPermSize=512m
-XX:PermSize=256m- verbose GC
– JMX API
– JConsole
– 其他監控工具Java HotSpot虛擬機持久代空間
是一種JVM存儲,主要用於存儲
Class對象,如類名 ,類方法,
內部JVM對象和其他JIT優化
相關的數據。本地堆(C-堆)不支持直接配置。
對於32位的虛擬機,
C堆容量= 4 Gig –堆 – 持久代
對於64位的虛擬機,C堆容量=
服務器總物理內存
&虛擬內存-堆-持久代- 在Windows 和Linux上檢查
整個進程大小
– Solaris 和Linux 下用pmap命令行
– AIX上用svmon命令C堆保存各種對象如MMAP文件,
其他JVM和第三方本地代碼對象。
Java堆空間 – 概覽 & 生命周期
你的Java程序生命周期通常看起來像這樣:
• Java 程序編碼(via Eclipse IDE etc.) ,例如 HelloWorld.java
• Java 程序編譯 (Java 編譯器或者第三方編譯工具如Apache Ant, Apache Maven..),例如 HelloWord.class
• Java 程序啟動和運行,例如通過HelloWorld.main() 方法運行。
現在我們來分析你的HelloWorld.class 程序,這樣你能更好理解。
• 啟動時,JVM會加載並把一些你的靜態程序以及JDK庫緩存到本地堆裏麵,包括本地庫,映射文件比如你的程序Jar文件,線程比如你的程序的主啟動線程等。
• JVM此時會保存你的HelloWorld.class的“靜態”數據到持久代空間(Class元數據,描述信息等)
• 一旦你的程序啟動,JVM開始管理,並在Java堆裏為程序動態的分配內存(年輕代和老年代),這也是為什麼了解你的程序需要多大內存空間是如此重要,你可以通過-Xms & -Xmx 的JVM參數恰當的調整你的Java堆大小。通過性能分析,堆轉儲分析允許你來決定程序的內存占用。
• 最終,當你的程序不再需要內存時,JVM也會動態的從堆裏釋放內存,這叫垃圾收集。這個過程通過JVM verbose GC或者一個監控工具比如Jconsole能很容易的監控到。
Java HotSpot 虛擬機持久代
Java HotSpot虛擬機持久代是JVM用來存儲你的Java程序Class對象。Java堆主要用來保存實際的短期或者長期的持久代Class對象實例。
持久代本身是完全靜態的,除非用第三方工具或者動態類加載中經常用到的Java反射API。
有一點很重要需要注意,這種內存存儲方式隻應用在Java Hotspot虛擬機上,其他的JVM比如IBM 和Oracle JRockit是沒有這種固定以及可配置的持久代存儲,它是用其他技術去管理非堆內存(本地內存)。
找到下麵一張圖,它描述了JVM HotSpot Java堆 vs 持久代 並分析他們各自關聯的的屬性和容量參數調整。
除了Oracle HotSpot JVM,還有其他各種供應商提供的虛擬機。接下來的部分我們將分析其他JVM的內存配置。理解HotSpot和其他虛擬機在實現和命名約定的不同也很重要。
IBM JVM 內存
IBM 虛擬機 內存分為2個區域:
• Java堆 Heap (年輕空間和年老空間)
• 本地堆(C-Heap)
這是他們的分析:
內存空間 | 啟動參數和調整方法 | 監控方式 | 描述 |
---|---|---|---|
Java 堆 | -Xmx (最大堆容量) -Xms (最小堆容量) – verbose GC – JMX API – IBM 監控工具 |
EX:
-Xmx1024m
-Xms1024m
GC 策略Ex:
-Xgcpolicy:gencon
(使gencon GC 策略生效)
-verbose GC
– JMX API
– IBM監控工具IBM Java 堆通常分為年輕代和
年老代(YoungGen, OldGen).
年輕代 GC 策略 (聯合了並發和分代GC)
通常用於Java EE 平台,為了最小化
GC暫停時間。本地堆 (C堆)不支持直接配置
對於32位虛擬機,C堆容量
= 4 Gig – Java堆
對於64位虛擬機,C堆容量 =
物理服務器總內存 & 虛擬內存
– Java堆
– svmon 命令C堆用來保存class元數據
對象,包括庫文件,其他
JVM以及第三方本地代碼對象。
也許你也注意到,IBM的虛擬機是沒有持久代的。持久代僅用於HotSpot虛擬機。IBM虛擬機是用本地堆保存相關數據的Class元數據。
Oracle也開始打算將持久代從HotSpot裏去掉,我們在接下來的部分會討論。
Oracle JRockit JVM 內存
JRockit 虛擬機內存分為2個部分:
• Java堆(年輕代和老年代)
• 本地內存空間(Class池,C堆,線程…)
內存空間 | 啟動參數和調整方法 | 監控方式 | 描述 |
---|---|---|---|
Java 堆 | -Xmx (最大堆容量) -Xms (最小堆容量) |
EX:
-Xmx1024m
-Xms1024m-verbose GC
– JMX API
– JRockit Mission
Control 工具集
JRockit Java堆通常分為年輕代
(短壽命對象)和年老代(長生命周期對象)。
本地內存空間不支持直接配置。
對32位虛擬機,本地內存空間容量
= 2-4 Gig – Java堆
** 依據你操作係統的不同,進程
大小限製 2 GB, 3 GB 或 4 GB
**
對64位虛擬機,本地內存空間容量
= 物理機總內存 &虛擬內存– Java堆
– 在Windows和Linux上
檢查總進程大小
– Solaris & Linux 的
pmap 命令行
– JRockit JRCMD 工具
JRockit本地內存空間用
於存儲Class元數據,線程
以及各種對象如庫文件,
其他JVM和第三方本地代碼對象。
和IBM虛擬機類似,JRockit也沒有持久代,它使用本地堆存儲相關對的Class元數據。
JRockit傾向於用更多的本地內存達到更好的性能。它沒有解釋模式,隻有編譯模式,由於它多了本地內存,和同等大小的Sun JVM相比,進程需要的大小通常會大好幾百M 。但這不是一個大問題,除非你使用32位的JRockit並加上很大堆空間。這種方式下,對於JRockit(對於32位虛擬機來說,堆越大留個本地堆的就越小)來說,OutOfMemoryError的危險性歸咎於本地堆消耗過高 。
HotSpot和JRockit的提供商Oracle的策略,是將這2個虛擬機合成一個,並且包含2個的優點和特性。這也使得JVM調優變得簡單,因為未能理解這2個虛擬機的不同會導致錯誤的調優建議和性能問題。
譯者介紹:
梅小西
Java工程師,關注JVM,並發編程,喜歡研究Python,Scala,Golang等。
最後更新:2017-05-22 15:34:50