1. 程式人生 > >Java執行時資料區域劃分

Java執行時資料區域劃分

轉自:https://www.cnblogs.com/zawier/p/6816781.html?utm_source=itdadao&utm_medium=referral

Java虛擬機器在執行Java程式的過程中會把它所管理的記憶體劃分為若干個不同的資料區域。這些區域都有各自的用途,以及建立和銷燬時間。根據《Java虛擬機器規範(Java SE 7版》的規定,Java虛擬機器所管理的記憶體將會包括以下幾個執行時資料區域,如下圖所示。

程式計數器

程式計數器是一塊較小的記憶體空間,它可以看做是當前執行緒(每個執行緒都有一個獨立的程式計數器)所執行的位元組碼的行號指示器。

Java虛擬機器棧

Java虛擬機器棧也是也是執行緒私有的。虛擬機器棧描述的是Java方法執行的記憶體模型:每個方法在執行的同時都會建立一個棧幀用於儲存區域性變量表、運算元棧、動態連結、方法出口等資訊。每一個方法從呼叫直至執行完成的過程,就對應著一個棧幀在虛擬機器棧中入棧到出棧的過程。

我們平時把Java記憶體區分為堆記憶體棧記憶體,其中的棧記憶體就是虛擬機器棧中的區域性變量表部分。

(如果執行緒請求的深度大於虛擬機器所允許的深度,將丟擲StackOverflowError異常;如果虛擬機器可以動態擴充套件,擴充套件時仍無法申請到足夠的記憶體,就會丟擲OutOfMemoryError異常)

本地方法棧

本地方法棧與虛擬機器棧所發揮的作用是非常相似的,它們之間的區別不過是虛擬機器棧為虛擬機器執行Java方法服務,而本地方法棧則為虛擬機器使用到的Native方法服務。

Java堆

Java堆是被所有執行緒共享的一塊記憶體區域,在虛擬機器啟動時建立。此記憶體區域的唯一目的就是存放物件例項,幾乎所有的物件例項都在這裡分配記憶體。

(如果在堆中沒有記憶體完成例項分配,並且堆也無法再擴充套件時,將會丟擲OutOfMemoryError異常)

方法區

方法區也是各個執行緒共享的記憶體區域,它用於儲存已被虛擬機器載入的類資訊常量靜態變數即時編譯器編譯後的程式碼等資料。

(當方法區無法滿足記憶體分配的需求時,將丟擲OutOfMemoryError異常)

執行時常量池(方法區的一部分)

Class檔案中除了有類的版本、欄位、方法、介面等描述資訊外,還有一項資訊是常量池,用於存放編譯器生成的各種字面量和符號引用,這部分內容將在類載入後進入方法區的執行時常量池中存放。

(當常量池無法再申請到記憶體時會丟擲OutOfMemoryError異常)

直接記憶體

直接記憶體不是虛擬機器執行時資料區的一部分,也不是Java虛擬機器規範中定義的記憶體區域。Java NIO可以使用Native函式庫直接分配堆外記憶體,然後通過一個儲存在Java堆中的DirectByteBuffer物件作為這塊記憶體的引用進行操作。

(這塊區域也會在記憶體不足時,動態擴展出現OutOfMemoryError異常)