JVM內存結構
- Java的內存結構布局
JVM的內存結構主要由三大塊:堆內存、方法區、棧。堆內存時JVM中最大的一塊,由年輕代和老年代組成。年輕代又被分成三部分,Eden空間、From Survivor空間、To Survivor空間,三部分默認情況下為8:1:1的比例分配空間。
下圖更詳細的描述了Java內存各部分的分配情況,以及通過哪些參數來控制各個區域的大小。
控制參數
-Xms設置堆的最小空間大小。
-Xmx設置堆的最大空間大小。
-XX:NewSize設置新生代最小空間大小。
-XX:MaxNewSize設置新生代最大空間大小。
-XX:PermSize設置永久代最小空間大小。
-XX:MaxPermSize設置永久代最大空間大小。
-Xss設置每個線程的堆棧大小
通過上圖可以看出,棧中又包含程序計數器(Program Counter Register)、JVM棧(JVM Stacks)和本地方法棧(Native Method Stacks)。
下面是對JAVA內存各個區域的詳細介紹:
Java堆:
Java堆是被所有線程共享的一塊內存區域,在虛擬機啟動時創建。Java堆的目的主要是存放對象實例,幾乎所有的對象實例都在這裏分配內存(TLAB(Thread Local Allocation Buffer)並不是分配在堆上,參見http://blog.csdn.net/rickiyeat/article/details/76802085?locationnum=4&fps=1),所以Java堆是Java虛擬機管理的內存中最大的一塊。
Java堆可以處於物理上不連續的內存空間中,只要邏輯上是連續的即可。Java堆是垃圾收集器管理的主要區域。
如果在堆中沒有內存來完成實例分配,並且堆也無法擴展時,將會拋出OutofMemoryError異常。
方法區(Method Area):
方法區與Java堆一樣,也是各個線程共享的內存區域,它用於存儲已被虛擬機加載的類信息、常量、靜態變量、即時編譯器編譯後的代碼等數據。(所謂即時編譯器的定義:即時編譯器(Just In Time Compiler) 簡稱JIT,JAVA程序最初是通過解釋器(Interpreter)進行解釋執行的,當JVM發現某個方法或代碼塊運行特別頻繁的時候,就會認為這是“熱點代碼”(Hot Spot Code)。
根據Java虛擬機規範的規定,當方法區無法滿足內存分配需求時,將拋出OutOfMemoryError異常。
程序計數器(Program Counter Register):
程序計數器的作用可以看做是當前線程所執行的字節碼的行號指示器,是線程私有的。如果線程正在執行的是一個Java方法,這個計數器記錄的是正在執行的虛擬機的虛擬機字節碼指令的地址;如果正在執行的是Native方法,這個計數器的值則為空。
此內存區域是唯一一個在Java虛擬機規範中沒有規定任何OutOfMemoryError情況的區域。
JVM棧:
Java虛擬機棧是線程私有的,它描述的是Java方法執行的內存模型:每個方法被執行的時候都會創建一個棧幀,用於存儲局部變量表、操作棧、動態鏈接、方法出口等信息。每一個方法被調用直至執行完成的過程,就對應著一個棧幀在虛擬機棧中從入棧到出棧的過程。局部變量表存放了編譯器可知的各種基本數據類型、對象引用和returnAddress類型。
在Java虛擬機規範中,對這個區域規定了兩種異常狀況:如果線程請求的棧深度大於虛擬機所允許的深度,將拋出StackOverflowError異常;如果虛擬機棧可以動態擴展(當前大部分的Java虛擬機都可動態擴展,只不過Java虛擬機規範中也允許固定長度的虛擬機棧),當擴展時無法申請到足夠的內存時會拋出OutOfMemoryError異常。
本地方法棧(Native Method Stacks):
本地方法棧(Native Method Stacks)與虛擬機棧所發揮的作用是非常相似的,其區別不過是虛擬機棧為虛擬機執行Java方法(也就是字節碼)服務,而本地方法棧則是為虛擬機使用到的Native方法服務。
轉載自:https://www.cnblogs.com/ityouknow/p/5610232.html
JVM內存結構