英文原文連接,
譯文連接,原文做者:Abhishek Gupta ,譯者:有孚
本文會介紹一些JVM內存結構的基本概念,而後很快會講到持久代,來看下Java SE 8發佈後它究竟到哪去了。 html
基礎知識
JVM只不過是運行在你係統上的另外一個進程而已,這一切的魔法始於一個java命令。正如任何一個操做系統進程那樣,JVM也須要內存來完成它的運 行時操做。記住——JVM自己是硬件的一層軟件抽象,在這之上纔可以運行Java程序,也纔有了咱們所吹噓的平臺獨立性以及WORA(一次編寫,到處運 行)。 java
快速過一遍JVM的內存結構
正如虛擬機規範所說的那樣,JVM中的內存分爲5個虛擬的區域。 緩存
堆
- 你的Java程序中所分配的每個對象都須要存儲在內存裏。堆是這些實例化的對象所存儲的地方。是的——都怪new操做符,是它把你的Java堆都佔滿了的!
- 它由全部線程共享
- 當堆耗盡的時候,JVM會拋出java.lang.OutOfMemoryError 異常
- 堆的大小能夠經過JVM選項-Xms和-Xmx來進行調整
堆被分爲: oracle
- Eden區 —— 新對象或者生命週期很短的對象會存儲在這個區域中,這個區的大小能夠經過-XX:NewSize和-XX:MaxNewSize參數來調整。新生代GC(垃圾回收器)會清理這一區域。
- Survivor區 —— 那些歷經了Eden區的垃圾回收仍能存活下來的依舊存在引用的對象會待在這個區域。這個區的大小能夠由JVM參數-XX:SurvivorRatio來進行調節。
- 老年代 —— 那些在歷經了Eden區和Survivor區的屢次GC後仍然存活下來的對象(固然了,是拜那些揮之不去的引用所賜)會存儲在這個區裏。這個區會由一個特殊的垃圾回收器來負責。年老代中的對象的回收是由老年代的GC(major GC)來進行的。
方法區
也被稱爲非堆區域(在HotSpot JVM的實現當中)
它被分爲兩個主要的子區域 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內存分區的基礎知識了。如今再說說持久代這個話題吧。 spa
那麼持久代上哪去了?
事實上,持久代已經被完全刪除了,取代它的是另外一個內存區域也被稱爲元空間。 操作系統
元空間 —— 快速入門
- 它是本地堆內存中的一部分
- 它能夠經過-XX:MetaspaceSize和-XX:MaxMetaspaceSize來進行調整
- 當到達XX:MetaspaceSize所指定的閾值後會開始進行清理該區域
- 若是本地空間的內存用盡了會收到java.lang.OutOfMemoryError: Metadata space的錯誤信息。
- 和持久代相關的JVM參數-XX:PermSize及-XX:MaxPermSize將會被忽略掉。
固然了,這只是冰山一角。想要更深刻地瞭解JVM,最好的資料莫過於它本身的虛擬機規範了! 線程