標籤:http io os ar java 資料 sp 2014 art
英文原文連結, 譯文連結,原文Abhishek Gupta ,譯者:有孚
本文會介紹一些JVM記憶體結構的基本概念,然後很快會講到持久代,來看下Java SE 8發布後它究竟到哪去了。
基礎知識
JVM只不過是運行在你系統上的另一個進程而已,這一切的魔法始於一個java命令。正如任何一個作業系統進程那樣,JVM也需要記憶體來完成它的運 行時操作。記住——JVM本身是硬體的一層軟體抽象,在這之上才能夠運行Java程式,也才有了我們所吹噓的平台獨立性以及WORA(一次編寫,處處運 行)。
快速過一遍JVM的記憶體結構
正如虛擬機器規範所說的那樣,JVM中的記憶體分為5個虛擬地區。
堆
- 你的Java程式中所分配的每一個對象都需要儲存在記憶體裡。堆是這些執行個體化的對象所儲存的地方。是的——都怪new操作符,是它把你的Java堆都佔滿了的!
- 它由所有線程共用
- 當堆耗盡的時候,JVM會拋出java.lang.OutOfMemoryError 異常
- 堆的大小可以通過JVM選項-Xms和-Xmx來進行調整
堆被分為:
- Eden區 —— 新對象或者生命週期很短的對象會儲存在這個地區中,這個區的大小可以通過-XX:NewSize和-XX:MaxNewSize參數來調整。新生代GC(記憶體回收行程)會清理這一地區。
- Survivor區 —— 那些曆經了Eden區的記憶體回收仍能存活下來的依舊存在引用的對象會待在這個地區。這個區的大小可以由JVM參數-XX:SurvivorRatio來進行調節。
- 老年代 —— 那些在曆經了Eden區和Survivor區的多次GC後仍然存活下來的對象(當然了,是拜那些揮之不去的引用所賜)會儲存在這個區裡。這個區會由一個特殊的記憶體回收行程來負責。年老代中的對象的回收是由老年代的GC(major GC)來進行的。
方法區
也被稱為非堆地區(在HotSpot JVM的實現當中)
它被分為兩個主要的子領域
- 持久代 —— 這個地區會儲存包括類定義,結構,欄位,方法(資料及代碼)以及常量在內的類相關資料。它可以通過-XX:PermSize及 -XX:MaxPermSize來進行調節。如果它的空間用完了,會導致java.lang.OutOfMemoryError: PermGen space的異常。
- 代碼緩衝——這個快取區域是用來儲存編譯後的代碼。編譯後的代碼就是本地代碼(硬體相關的),它是由JIT(Just In Time)編譯器產生的,這個編譯器是Oracle HotSpot JVM所特有的。
JVM棧
- 和Java類中的方法密切相關
- 它會儲存局部變數以及方法調用的中間結果及傳回值
- Java中的每個線程都有自己專屬的棧,這個棧是別的線程無法訪問的。
- 可以通過JVM選項-Xss來進行調整
本地棧
PC寄存器
- 特定線程的程式計數器
- 包含JVM正在執行的指令的地址(如果是本地方法的話它的值則未定義)
好吧,這就是JVM記憶體分區的基礎知識了。現在再說說持久代這個話題吧。
那麼持久代上哪去了?
事實上,持久代已經被徹底刪除了,取代它的是另一個記憶體地區也被稱為元空間。
元空間 —— 快速入門
- 它是本地堆記憶體中的一部分
- 它可以通過-XX:MetaspaceSize和-XX:MaxMetaspaceSize來進行調整
- 當到達XX:MetaspaceSize所指定的閾值後會開始進行清理該地區
- 如果本地空間的記憶體用盡了會收到java.lang.OutOfMemoryError: Metadata space的錯誤資訊。
- 和持久代相關的JVM參數-XX:PermSize及-XX:MaxPermSize將會被忽略掉。
當然了,這隻是冰山一角。想要更深入地瞭解JVM,最好的資料莫過於它自己的虛擬機器規範了!
JVM的持久代——何去何從?