JVM內存結構

原文地址:博學無憂c++

在Java語言開發過程當中,out of memory錯誤是很常見的一種錯誤。對於JVM的內存結構有更深刻的瞭解,更更好的幫咱們排查此類問題,有效的避免此類問題發生。在JAVA 8中內存結構有進行了改變,Metaspace替代了PermGen。數組

 內存結構簡介網絡

JVM的內存結構以下圖所示:(圖片來源於網絡)jvm

JVM的內存結構大概分爲:佈局

  • 堆(heap):線程共享,全部的對象實例以及數組都要在堆上分配。回收器主要管理的對象。
  • 方法區(MEATHOD AREA):線程共享,存儲類信息、常量、靜態變量、即時編譯器編譯後的代碼。
  • PC寄存器(PC Register):線程私有。指向下一條要執行的指令。
  • 方法棧(JVM Stack):線程私有、存儲局部變量表、操做棧、動態連接、方法出口,對象指針。
  • 本地方法棧(NATIVE METHOD STACK):線程私有。爲虛擬機使用到的Native 方法服務。如Java使用c或者c++編寫的接口服務時,代碼在此區運行。

各區域詳細說明

先看一張圖,這張圖能很清晰的說明JVM內存結構的佈局和相應的控制參數:(圖片來源於網絡)spa

堆的做用是存放對象實例和數組。堆從結構上來分,能夠分爲新生代和老生代。而新生代又能夠分爲Eden 空間、From Survivor 空間(s0)、To Survivor 空間(s1)。 全部新生成的對象首先都是放在年輕代的。須要注意,Survivor的兩個區是對稱的,沒前後關係,因此同一個區中可能同時存在從Eden複製過來 對象,和從前一個Survivor複製過來的對象,而複製到年老區的只有從第一個Survivor去過來的對象。並且,Survivor區總有一個是空的。線程

控制參數
-Xms設置堆的最小空間大小。-Xmx設置堆的最大空間大小。-XX:NewSize設置新生代最小空間大小。-XX:MaxNewSize設置新生代最小空間大小。設計

垃圾回收
此區域是垃圾回收的主要操做區域。指針

異常狀況
若是在堆中沒有內存完成實例分配,而且堆也沒法再擴展時,將會拋出OutOfMemoryError 異常。對象

方法區

方法區(Method Area)與Java 堆同樣,是各個線程共享的內存區域,它用於存儲已被虛擬機加載的類信息、常量、靜態變量、即時編譯器編譯後的代碼等數據。雖然Java 虛擬機規範把方法區描述爲堆的一個邏輯部分,可是它卻有一個別名叫作Non-Heap(非堆),目的應該是與Java 堆區分開來。
不少人願意把方法區稱爲「永久代」(Permanent Generation),本質上二者並不等價,僅僅是由於HotSpot虛
擬機的設計團隊選擇把GC 分代收集擴展至方法區,或者說使用永久代來實現方法區而已。對於其餘虛擬機(如BEA JRockit、IBM J9 等)來講是不存在永久代的概念的。在Java8中永生代完全消失了。

控制參數
-XX:PermSize 設置最小空間 -XX:MaxPermSize 設置最大空間

垃圾回收
對此區域會涉及可是不多進行垃圾回收。這個區域的內存回收目標主要是針對常量池的回收和對類型的卸載,通常來講這個區域的回收「成績」比較難以使人滿意。

異常狀況
根據Java 虛擬機規範的規定, 當方法區沒法知足內存分配需求時, 將拋出
OutOfMemoryError 異常。

PC計數器

它的做用能夠看作是當前線程所執行的字節碼的行號指示器。

異常狀況
此內存區域是惟一一個在Java 虛擬機規範中沒有規定任何OutOfMemoryError 狀況的區域。

方法棧

每一個線程會有一個私有的棧。每一個線程中方法的調用又會在本棧中建立一個棧幀。在方法棧中會存放編譯期可知的各類基本數據類型(boolean、byte、char、short、int、float、long、double)、對象引用(reference 類型,它不等同於對象自己。局部變量表所需的內存空間在編譯期間完成分配,當進入一個方法時,這個方法須要在幀中分配多大的局部變量空間是徹底肯定的,在方法運行期間不會改變局部變量表的大小。

控制參數
-Xss控制每一個線程棧的大小。

異常狀況
在Java 虛擬機規範中,對這個區域規定了兩種異常情況:
將拋出StackOverflowError: 異常線程請求的棧深度大
於虛擬機所容許的深度時拋出;
OutOfMemoryError 異常: 虛擬機棧能夠動態擴展,當擴展時沒法申請到足夠的內存時會拋出。

本地方法棧

本地方法棧(Native Method Stacks)與虛擬機棧所發揮的做用是很是類似的,其
區別不過是虛擬機棧爲虛擬機執行Java 方法(也就是字節碼)服務,而本地方法棧則
是爲虛擬機使用到的Native 方法服務。

控制參數
在Sun JDK中本地方法棧和方法棧是同一個,所以也能夠用-Xss控制每一個線程的大小。

異常狀況 與虛擬機棧同樣,本地方法棧區域也會拋出StackOverflowError 和OutOfMemoryError 異常。

相關文章
相關標籤/搜索