JVM 執行時期資料區 (JVM Runtime Area) 其實是指 JVM 在運作期間,其對JVM記憶體空間的分割與分配。網路上找到兩張圖如下圖所示(個人認為第二張圖Native Method Stack應該畫在Java Thead模組中):
#堆疊分為java虛擬機器堆疊與本機方法堆疊
#重點是Java虛擬機棧,它是執行緒私有的,生命週期與執行緒相同。
每個方法執行都會建立一個堆疊幀,用於存放局部變數表,操作棧,動態鏈接,方法出口等。每個方法從被調用,直到被執行完。對應一個堆疊幀在虛擬機器中從入棧到出棧的過程。
通常說的堆疊是指局部變數表部分,存放編譯期間可知的8種基本資料類型,及物件參考和指令位址。局部變數表是在編譯期間完成分配,當進入一個方法時,這個堆疊中的局部變數分配記憶體大小是確定的。
會有兩種例外StackOverFlowError和 OutOfMemoneyError。當執行緒請求堆疊深度大於虛擬機器所允許的深度就會拋出StackOverFlowError錯誤;虛擬機棧動態擴展,當擴充功能無法申請到足夠的記憶體空間時候,拋出OutOfMemoneyError。
本地方法堆疊為虛擬機器使用到的本機方法服務(native),也是執行緒私有的。
#堆被所有執行緒共享區域,在虛擬機器啟動時創建,唯一目的存放物件實例。
堆區是gc的主要區域,通常情況下分為兩個區塊年輕代和年老代。更細一點年輕代又分為Eden區最要放新創建對象,From survivor 和 To survivor 保存gc後倖存下的對象,默認情況下各自佔比 8:1:1。
不過很多文章介紹分成3個區塊,把方法區算為永久代。這大概是基於Hotspot虛擬機器劃分, 然後例如IBM j9就不存在永久代概論。不管怎麼分區,都是存放物件實例。
會有異常OutOfMemoneyError
被所有執行緒共享區域,用於存放
已被虛擬機載入常數池用於存放編譯期產生的各種字節碼和符號引用,常數池具有一定的動態性
,裡面可以存放編譯期產生的常數;4、
程式計數器#目前執行緒所執行的
Java虛擬機器多執行緒是透過執行緒輪流切換並分配處理器執行時間的方式實現的。 為了執行緒切換能恢復到正確的位置,每個執行緒都需要一個獨立的程式計數器,所以它是執行緒私有的 。 |
唯一一塊Java虛擬機器沒有 規定任何OutofMemoryError的區塊 |
三、資料區域總表 |
#名稱 |
」特徵 ######### ######作用##################設定參數##################異常##### ## |
程式計數器 |
佔用記憶體小,執行緒私有,生命週期與執行緒相同 |
#大致為字節碼行號指示器 |
#無 |
#無 |
虛擬機器堆疊 |
線程私有,生命週期與執行緒相同,使用連續的記憶體空間 |
Java 方法執行的記憶體模型,儲存局部變數表、操作堆疊、動態連結、方法出口等資訊 |
-Xss |
StackOverflowError OutOfMemoryError |
java堆疊 |
##線程共享,生命週期與虛擬機器相同,可以 不使用連續的記憶體位址 |
儲存物件實例,所有物件實例(包括陣列)都要在堆上分配 | #-Xms-Xsx-Xmn | #OutOfMemoryError |
#方法區 | 執行緒共享,生命週期與虛擬機器相同,可以 不使用連續的記憶體位址 | 儲存已被虛擬機器載入的類別資訊、常數、靜態變數、即時編譯器編譯後的程式碼等資料 | -XX:PermSize:16M #-XX:MaxPermSize:64M | OutOfMemoryError |
方法區的一部分,具有動態性 | 。存放字面量及符號參考 |
在JDK 1.4 中新加入了NIO(NewInput/Output)類,引入了一種基於通道(Channel)與緩衝區(Buffer)的I/O 方式,它可以使用Native 函數庫直接分配堆外內存,然後透過一個儲存在Java 堆裡面的DirectByteBuffer 物件作為這塊內存的引用進行操作。這樣能在一些場景中顯著提高效能,因為避免了在Java 堆和Native 堆中來回複製資料。
五、延伸:堆疊與堆疊的比較
堆很靈活,但是不安全。對於對象,我們要動態地創建、銷毀,不能說後創建的對象沒有銷毀,先前創建的對象就不能銷毀,那樣的話我們的程序就寸步難行,所以Java中用堆來存儲對象。而一旦堆中的物件被銷毀,我們繼續引用這個物件的話,就會出現著名的 NullPointerException,這就是堆的缺點——錯誤的引用邏輯只會在運行時才會被發現。
堆疊不靈活,但是很嚴格,是安全的,易於管理。因為只要上面的引用沒有銷毀,下面引用就一定還在,在大部分程式中,都是先定義的變數、引用先進棧,後定義的後進棧,同時,區塊內部的變數、引用在進入區塊時壓棧,區塊結束時出棧,理解了這個機制,我們就可以很方便地理解各種程式語言的作用域的概念了,同時這也是棧的優點——錯誤的引用邏輯在編譯時就可以被發現。
堆疊--主要存放參考和基本資料型別。
堆--用來存放 new 出來的物件實例。
參考:
#以上是JVM記憶體模型圖文實例的詳細內容。更多資訊請關注PHP中文網其他相關文章!