JVM 內存模型

Center

1. 虛擬機棧 VM Stack

線程私有,生命週期與線程相同。VM Stack是描述Java方法執行的內存模型:每一個方法執行的時候會同時建立一個棧幀(Stack Frame),用於存儲局部變量表、操做數棧、動態鏈接、返回地址、方法出口等信息。算法

  • 局部變量表:用於存放方法參數和方法內部定義的局部變量。虛擬機是使用局部變量表完成參數值到參數變量表的傳遞過程。安全

  • 操做數棧:虛擬機把操做數棧做爲它的工做區。(相似於寄存器,用於存儲指令操做須要的數據。)佈局

  • 動態鏈接:『符號引用』是每一個方法的『間接引用』,『符號引用』指向方法的內存位置,調用方法前須要把『符號引用』轉換爲『直接引用』。spa

    • 若是在類加載階段或者第一次調用時,把『符號引用』轉爲『直接引用』,稱爲『靜態解析』。.net

    • 若是在運行期間轉爲『直接引用』,稱爲『動態鏈接』。線程

  • 返回地址:退出方法時要返回的位置。code

棧的異常

  • StackOverflowError:若是線程請求的棧深度大於虛擬機所容許的深度,將拋出StackOverFlowError。如無限遞歸調用當前方法。對象

  • OutOfMemoryError:若是VM Stack能夠動態擴展,當擴展時沒法申請到足夠的內存時,將拋出OutOfMemoryError。blog

2. 本地方法棧 Native Method Stack

跟VM Stack很像,可是VM Stack爲執行Java方法服務,Native Method Stack爲執行Native方法服務。在Sun HotSpot虛擬中,把VM Stack和Native Method Stack合二爲一。遞歸

3. 堆 Heap

JVM內存管理最大的一塊。被Java線程共享的內存區域
惟一功能就是存放對象實例。
堆是垃圾回收器管理的主要區域。,也被稱爲『GC堆』。

根據垃圾回收分代收集算法,Heap分爲新生代和老年代

  • 新生代:程序建立新對象都重新生代分配內存。新生代分爲Eden Space和Survivor Space(進入老年代的中轉區)。

  • 老年代:經歷屢次新生代GC(Young GC)仍然存活的對象。

4. 方法區 Method Area

存放class的元數據信息:類名、字段信息、方法信息等 。另外還有類的常量集合:包括實際的常量和對類型、域和方法的符號引用。
簡言之,方法區=class信息+運行時常量池。
常常被稱爲永久代。

方法區的特色:

  • 線程安全。因爲全部線程都共享方法區,必須是線程安全的(同步的)。

  • 大小不固定,也不是連續的,能夠在Heap中分配。

  • 能夠被GC,當某個類再也不使用時,JVM將卸載這個類,並進行GC。

能夠經過-XX:PermSize 和 -XX:MaxPermSize 參數限制方法區的大小。

5. 程序計數器

程序計數器是一塊較小的內存空間,能夠看做是當前線程所執行的字節碼的行號指示器。分支、循環、跳轉、異常處理、線程恢復等基礎功能都須要依賴這個計數器來完成。
此內存區域是惟一一個在Java 虛擬機規範中沒有規定任何OutOfMemoryError狀況的區域。

總結

圖片描述

內存分配過程

  1. JVM 會試圖爲相關Java對象在Eden Space中初始化一塊內存區域。

  2. 當Eden空間足夠時,內存申請結束;不然到下一步。

  3. JVM 試圖釋放在Eden中全部不活躍的對象(這屬於1或更高級的垃圾回收)。釋放後若Eden空間仍然不足以放入新對象,則試圖將部分Eden中活躍對象放入Survivor區。

  4. Survivor區被用來做爲Eden及Old的中間交換區域,當Old區空間足夠時,Survivor區的對象會被移到Old區,不然會被保留在Survivor區。

  5. 當Old區空間不夠時,JVM 會在Old區進行徹底的垃圾收集(0級)。

  6. 徹底垃圾收集後,若Survivor及Old區仍然沒法存放從Eden複製過來的部分對象,致使JVM沒法在Eden區爲新對象建立內存區域,則出現「outofmemory」錯誤。

對象內存訪問

即便是最簡單的訪問,也會卻涉及Java 棧、Java 堆、方法區這三個最重要內存區域之間的關聯關係,以下面的這句代碼:

Object obj = newObject();
  • VM Stack:「Object obj」這部分的語義將會反映到VM Stack的本地變量表中,做爲一個reference 類型數據出現。

  • Heap:而「new Object()」這部分的語義將會反映到Java 堆中,造成一塊存儲了Object 類型全部實例數據值(Instance Data,對象中各個實例字段的數據)的結構化內存,根據具體類型以及虛擬機實現的對象內存佈局(Object Memory Layout)的不一樣,這塊內存的長度是不固定的。

  • 方法區:另外,在Java 堆中還必須包含能查找到此對象類型數據(如對象類型、父類、實現的接口、方法等)的地址信息,這些類型數據則存儲在方法區中。


原文地址:http://blog.csdn.net/u0121526...

相關文章
相關標籤/搜索