JVM的持久代——何去何從?

英文原文連接譯文連接,原文做者:Abhishek Gupta ,譯者:有孚

本文會介紹一些JVM內存結構的基本概念,而後很快會講到持久代,來看下Java SE 8發佈後它究竟到哪去了。 html

基礎知識

JVM只不過是運行在你係統上的另外一個進程而已,這一切的魔法始於一個java命令。正如任何一個操做系統進程那樣,JVM也須要內存來完成它的運 行時操做。記住——JVM自己是硬件的一層軟件抽象,在這之上纔可以運行Java程序,也纔有了咱們所吹噓的平臺獨立性以及WORA(一次編寫,到處運 行)。 java

快速過一遍JVM的內存結構

正如虛擬機規範所說的那樣,JVM中的內存分爲5個虛擬的區域。 緩存

  • 方法區(非堆)
  • JVM棧
  • 本地棧
  • PC寄存器

  • 你的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來進行調整

本地棧

  • 用於本地方法(非Java代碼)
  • 按線程分配

PC寄存器

  • 特定線程的程序計數器
  • 包含JVM正在執行的指令的地址(若是是本地方法的話它的值則未定義)

好吧,這就是JVM內存分區的基礎知識了。如今再說說持久代這個話題吧。 spa

那麼持久代上哪去了?

事實上,持久代已經被完全刪除了,取代它的是另外一個內存區域也被稱爲元空間。 操作系統

元空間 —— 快速入門

  • 它是本地堆內存中的一部分
  • 它能夠經過-XX:MetaspaceSize和-XX:MaxMetaspaceSize來進行調整
  • 當到達XX:MetaspaceSize所指定的閾值後會開始進行清理該區域
  • 若是本地空間的內存用盡了會收到java.lang.OutOfMemoryError: Metadata space的錯誤信息。
  • 和持久代相關的JVM參數-XX:PermSize及-XX:MaxPermSize將會被忽略掉。

固然了,這只是冰山一角。想要更深刻地瞭解JVM,最好的資料莫過於它本身的虛擬機規範了! 線程

相關文章
相關標籤/搜索