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異常)