運行時數據區域
- 程序計數器(線程私有)
- 看作當前線程所執行的字節碼的行號指示器。
- 在虛擬機的概念模型中,字節碼的解釋器工作時就是通過改變這個計數器來 選取下一條需要執行的字節碼指令。
- java虛擬機棧(線程私有)
- 描述的是java方法(字節碼)執行的內存模型:每個方法在執行時都會創建一個棧幀用於存取局部變量表、操作數棧、動態鏈接、方法出口等信息。
- 局部變量表中存放編譯期可知的數據類型:
- 基本數據類型(boolean、byte、char、short、int、float、long、double)
- 對象引用
- returnAddress (指向一條字節碼指令的地址)
(注:long和double會佔據兩個局部變量空間,其餘類型佔據一個局部變量空間)
- 局部變量表內存空間在編譯期完成分配,在運行期不會改變。
- 內存溢出異常:
- StackOverflowError異常:線程請求的棧深度大於虛擬機所允許的深度。
- OutOfMemoryError異常:虛擬機棧動態擴展無法申請到足夠的內存。時。
- 本地方法棧(線程私有)
- 描述的是Native方法執行的內存模型。
- 虛擬機規範中對本地方法棧中的方法使用的語言,使用方式與數據結構並沒有強制規定。
- 內存溢出異常:
- StackOverflowError異常:線程請求的棧深度大於虛擬機所允許的深度。
- OutOfMemoryError異常:虛擬機棧動態擴展無法申請到足夠的內存。
- java堆(線程共享)
- 所有對象實例及數組都要在堆上分配內存。(有例外-棧上分配,標量替換)
- 垃圾收集器的主要管理區域。(具體細節將在垃圾回收機制中探討)
- 堆可以處於物理上不連續的內存空間,只要邏輯上連續即可。
- 內存溢出異常
- OutOfMemoryError異常:在堆中沒有內存去完成實例分配,並且堆也無法再擴展時。
- 方法區(線程共享)
- 存儲已被虛擬機加載的類信息、常量、靜態變量、即時編譯器編譯後的代碼等數據。
- 不需要物理上連續的內存,可以選擇不實現垃圾收集。
- 內存溢出異常
- OutOfMemoryError異常:當方法區無法滿足內存分配需求時。
- 運行時常量池(方法區的一部分)
- 用於存放編譯期生成的各種字面量和符號引用。(Class文件中,類加載後進入方法區的運行時常量池存放這些數據)
- 直接引用也存儲在運行時常量池。
- 運行時常量池具備動態性(運行期可改變,例:String類 intern()方法)
- 內存溢出異常
- OutOfMemoryError異常:當常量池無法申請內存。
- 直接內存(傳統意義上的物理內存)
- 不是虛擬機運行時數據區,也不是java虛擬機規範中定義的內存區域。
- NIO 可以使用Native函數庫直接分配堆外內存,能顯著提高性能。
- 內存溢出異常
- OutOfMemoryError異常:當各個內存區域總和大於物理內存限制(包括物理和操作系統的限制)。