1. 程式人生 > >JAVA執行時資料區域

JAVA執行時資料區域

java與C++之間有一堵由記憶體動態分配垃圾回收技術所圍成的“高牆”,裡面的人想出去,外面的人想進來。

參考資料:《深入理解Java虛擬機器:JVM高階特性與最佳實踐》 周志明 著

執行時資料區域

根據《java虛擬機器規範(java SE 7)》的規定,java虛擬機器所管理的記憶體將會包括以下幾個執行時資料區域。
java虛擬機器執行時資料區示意圖

1.程式計數器

這是一塊較小的記憶體空間,可以看做是當前執行緒所執行的位元組碼行號指示器,在虛擬機器的概念模型裡(不同虛擬機器中可能存在更高效的實現方式),位元組碼直譯器就是通過改變這個計數器的值來選取下一條需要執行的位元組碼指令,分支、迴圈、跳轉、異常處理、執行緒恢復等基礎功能依賴這個計數器來完成。
為了執行緒切換之後能回到正確的執行位置,每條執行緒都需要有一個獨立的程式計數器,因此程式計數器是私有的

2.java虛擬機器棧

虛擬機器棧描述的是java方法執行的記憶體模型。執行緒私有,生命週期與執行緒相同,每個方法執行時都會創造一個棧幀。棧幀用於儲存區域性變量表、運算元棧、動態連結、方法出口等資訊。每一個方法的執行都對應著一個棧幀在java虛擬機器棧中進棧出棧的過程。
值得注意的是,在方法執行期間,棧幀中區域性變量表所需要的空間是不會改變的,是在編譯時就已經確定了的。

3.本地方法棧

java虛擬機器棧為虛擬機器執行java方法,而本地方法棧為虛擬機器執行Native方法,即本地方法執行緒私有,這部分方法可能由虛擬機器使用C++/C或者其他語言實現,甚至有些虛擬機器(最常見的HotSpot虛擬機器)直接就把本地方法棧和虛擬機器棧合二為一。
java虛擬機器棧和本地方法棧都可能會丟擲棧異常和記憶體異常。

4.Java堆

對於大多數應用來說,JAVA Heap是JVM所管理的記憶體中最大的一塊,Java Heap是執行緒共享的,在JVM啟動時建立,幾乎所有物件例項都在這裡分配記憶體,這裡值得注意的是:在JVM規範中並未規定例項物件必須分配在JAVA堆中,對於Sun 公司的HotSpot虛擬機器而言,Class物件雖然是物件,但是它是被存放在方法區裡面。這個物件將作為程式訪問方法區中的某些型別資料的外部介面。
Java堆也是垃圾收集器管理的主要區域,因此很多時候也被稱作GC堆。在Java堆中,現在普遍還細分為新生代老年代,關於垃圾回收機制,後面我們會再進行詳細分析討論。
另外,根據JVM規範,Java堆可以在物理空間上不連續,只要邏輯上連續即可。可以通過(-Xmx和-Xms


控制擴充套件。

5.方法區

方法區也是執行緒共享,用於儲存已被JVM載入的類資訊常量靜態變數即時編譯器編譯後的程式碼等資料(當然,HotSpot中也需要儲存Class物件)。這個區域存在弱限制度的垃圾回收,而且該區域記憶體回收的目標主要針對常量池的回收和對型別的解除安裝

5.1方法區的一部分—-執行時常量池

Class檔案中有一項資訊是常量池,用於存放編譯期生成的各種字面量符號引用。這部分內容在類載入後進入方法區的執行時常量池存放。執行時常量池具有動態性,Java語言並不要求常量必須在編譯期產生,也就是並非預置入Class檔案中常量池的內容才能進入執行時常量池。執行期間也可以將常量放入常量池,這種特性利用最多的便是S**tring類的intern()方法**。

6.直接記憶體

直接記憶體並不是執行時資料區的一部分。在JDK1.4之後引入NIO類,引入了一種基於通道與緩衝區的IO方式,它可以使用Native函式庫直接分配堆外記憶體,然後通過一個儲存在JAVA堆中的DirectByteBuffer物件作為這塊記憶體的引用進行操作。這樣能夠避免在Java堆和Native堆中來回複製資料所引發的開銷。