The runtime data area model of JVM
瞭解執行時資料區模型是認識Java虛擬機器的重要前提。雖然說JVM甚至說較為常用的HotSpot虛擬機器本身就有自動分配和管理記憶體的功能,但是學習JVM是為了能夠在出錯的時候甚至在優化的時候能夠由開發人員自己去處理,虛擬機器提供的自動記憶體管理只能在合適或通常情況下是沒問題的。
執行時資料區又稱為Java虛擬機器執行時資料區,它的大體模型結構如下圖所示
執行時資料區其實就是一塊記憶體區域,按照不同的型別和功能進行劃分。主要有程式計數器,虛擬機器棧,本地方法棧,方法區和堆。
按照執行緒的使用情況可以分為執行緒私有和執行緒共享
其中方法區和堆屬於執行緒共享,而虛擬機器棧,本地方法棧和程式計數器屬於執行緒私有
程式計數器
程式計數器用於記錄Java程式執行時的位元組碼行號等相關資訊,線上程進行上下文切換時,迴圈,異常處理等進行計算和相關的記錄。如果程式執行的是本地方法,那麼程式計數器記錄的值應該是空的,僅有執行Java方法時才會有相應的位元組碼行號。每一個執行緒都持有一個程式計數器,並獨立儲存,是執行緒私有。程式計數器在記憶體分配中佔有較小的內容,主要的工作就是載入程式的執行。
虛擬機器棧和本地方法棧
虛擬機器棧和本地方法棧都是一塊管理方法執行的記憶體區域。並且也屬於執行緒私有,生命週期和執行緒相同。
虛擬機器棧管理的是Java方法的執行,每一次呼叫方法的時候,會通過棧幀進行相關資訊的儲存,然後棧幀入棧操作,呼叫結束後就會進行出棧。棧幀中主要儲存的是區域性變數表、運算元棧、動態連線、方法出口等資訊。
區域性變數表中存放了編譯期可知的各種Java虛擬機器基本資料型別、物件引用和returnAddress型別(指向一條位元組碼指令的地址)
資料型別在區域性變數表中是以區域性變數槽來表示,並且在編譯期間完成分配,方法執行期間是不會變更的。關鍵的是,long和double型別會佔用兩個變數槽,而其他型別只佔用一個。如果執行緒請求的棧的深度大於虛擬機器鎖執行的深度就會丟擲StackOverflowError異常;如果Java虛擬機器棧允許動態擴容,當無法申請到足夠的記憶體時則會丟擲OutOfMemoryError異常。
本地方法棧和虛擬機器棧基本相同,主要區別就是本地方法棧管理的是本地方法的執行。
Java堆
Java堆在JVM啟動的時候就建立了,是記憶體管理中最大的一塊區域,主要用於存放物件例項(包括陣列),是執行緒共享的。
Java堆也是垃圾收集器管理的記憶體區域,因此Java堆也被稱為GC堆。
從垃圾回收的角度上看,JVM會對不同物件例項的使用情況進行生命週期的管理,例如新生代,老年代的概念。
從記憶體分配的角度上看,除了一大部分用於存放物件,堆還有提供一小部分用於執行緒私有的分配緩衝區。這個分配快取區主要是為了提高物件分配的效率。
方法區
方法區主要用於儲存被虛擬機器載入的的型別資訊、常量、靜態變數、即時編譯器編譯後的程式碼快取等資料。方法區也同樣是執行緒共享的。
方法區也可以是垃圾回收器的管理物件。但主要是對執行時常量池的回收和型別的解除安裝。
方法區中有一個重要的部分就是執行時常量池。執行時常量池主要用於儲存常量表。在Class檔案中處理有類的版本、欄位、方法、介面等描述資訊外,還有常量池表。常量池表用於存放編譯器生成的各種字面量和符號引用,這部分記憶體在被類載入器載入後存放到方法區的常量池中。
執行時常量池相對於Class檔案常量池的另外一個重要特徵就是具備動態性。也就是說常量池中的內容並不一定只能通過編譯期間進行儲存,在程式執行期間也可以。典型的例子就行String類中的intern()方法。
intern()方法呼叫時會先檢查執行時常量池中是否已存在該常量,如果存在則直接返回該引用,否則將新的值儲存執行時常量池,並返回該引用。
以下例子演示了執行時常量池的動態性。
public class RuntimeDemo {
public static void main(String[] args) {
String a = "a";
String a1 = new String("a");
String a2 = new String ("a");
String a3 = new String("b");
/** a1是物件引用 */
System.out.println(a==a1);
/** intern()先檢查常量池中是否存在“a“的字面量常量,存在則將a2執行此常量,否則建立新的物件引用 */
System.out.println(a==a2.intern());
System.out.println(a==a3);
}
}
執行結果
false
true
false
直接記憶體
直接記憶體並不屬於JVM中記憶體管理中的一部分。
如果你瞭解NIO的相關知識,那麼你會更容易理解直接記憶體的意義。NIO的基本介紹可以看下這裡必須瞭解的三種IO操作--BIO、NIO、AIO
直接記憶體可以通過本地Native方法分配到主機的記憶體,這一塊記憶體會受到主機記憶體限制的直接影響,在NIO中,就有通過記憶體對映的方式提高程式的IO效率,實現原理就是通過Java本地緩衝區來對映主機實體記憶體的引用從而不需要進行從Java記憶體複製到實體記憶體的操作,提高了IO效率。
相關文章
- Code Area和Data Area有什麼區別
- LAMBDA: A Large Model Based Data Agent
- CDM(Conceptual Data Model,概念資料模型)和 PDM(Physical Data Model,物理資料模型)模型
- oracle data Format Models---二(轉)OracleORM
- As a reader --> TabDDPM: Modelling Tabular Data with Diffusion Models
- 利用Runtime寫一個JSON轉Model的工具JSON
- iOS開發之使用Runtime給Model類賦值iOS賦值
- 瞭解PowerDesigner的Logical Data Model
- Entity Framework Tutorial Basics(5):Create Entity Data ModelFramework
- iOS開發之遍歷Model類的屬性並完善使用Runtime給Model類賦值iOS賦值
- libtorch使用model.forward報std::runtime_error錯誤ForwardError
- sort_area_retained_size與sort_area_sizeAI
- delphi基於資料模型(data-model)JSON序列模型JSON
- Oracle 11gR2 fast recovery area = flash recovery areaOracleAST
- SAP S/4HANA New Simplified Data Model (NSDM) 模型介紹模型
- [譯]Swift: 利用 Enum 靈活對映多重型別 Data modelSwift型別
- c#之system.data.componentmodel名稱空間C#
- oracle Flash Revovery AreaOracle
- Oracle pending areaOracle
- 論文閱讀 A Data-Driven Graph Generative Model for Temporal Interaction Networks
- Sentry 監控 - Snuba 資料中臺架構(Data Model 簡介)架構
- 使用ElementUI和element-china-area-data庫實現省市區三級聯動元件封裝UI元件封裝
- 在SAP Data Intelligence Modeler裡建立新的pipelineIntel
- 設定Flash Recovery Area
- Overview of the System Global Area (70)View
- 【Fixed Area】從SGA的Fixed Area中得到系統當前的SCN號
- iOS Runtime(一) Runtime的應用iOS
- LeetCode-Rectangle AreaLeetCode
- In this new Buy fifa coins? area
- ASP.NET MVC系列:AreaASP.NETMVC
- HDU 4946 Area of Mushroom(凸包)OOM
- Difference between business area and profit center
- AutoPeftModel、AutoModel、PeftModel
- 禁止JVM執行外部命令Runtime.exec–由ApacheCommonsCollections漏洞引發的思考JVMApache
- Oracle8i中SORT_AREA_SIZE和SORT_AREA_RETAINED_SIZE的理解OracleAI
- Runtime理解
- iOS RuntimeiOS
- iOS~runtimeiOS