JVM內存區域的划分(內存結構或者內存模型)


運行時數據區域:

根據 JVM 規范,JVM 內存共分為虛擬機棧、堆、方法區、程序計數器、本地方法棧五個部分。

程序計數器(線程私有):

  是當前線程所執行的字節碼的行號指示器,每條線程都要有一個獨立的程序計數器,這類內存也稱為“線程私有”的內存。

  正在執行java方法的話,計數器記錄的是虛擬機字節碼指令的地址(當前指令的地址)。如果還是Native方法,則為空

  這個內存區域是唯一一個在虛擬機中沒有規定任何OutOfMemoryError情況的區域。

 

Java虛擬機棧(線程私有):

  也是線程私有的。

  每個方法在執行的時候會創建一個棧幀,存儲了局部變量表,操作數棧,動態連接,方法返回地址等。

  每個方法從調用到執行完畢,對應一個棧幀在虛擬機棧中的入棧和出棧。

  通常所說的棧,一般是指虛擬機棧中的局部變量表部分。

  局部變量表所需的內存在編譯期間完成分配。

  如果線程請求的棧深度大於虛擬機所允許的深度,則StackOverflowError。

    如果虛擬機棧可以動態擴展,擴展到無法申請足夠的內存,則OutOfMemoryError。

 

本地方法棧(線程私有):

  和虛擬機棧類似,主要為虛擬機使用到的Native方法服務。

  也會拋出StackOverflowError和OutOfMemoryError。

 

Java堆(線程共享):

  被所有線程共享的一塊內存區域,在虛擬機啟動時創建,用於存放對象實例

  堆可以按照可擴展來實現(通過-Xmx和-Xms來控制)

  當堆中沒有內存可以分配給實例,也無法再擴展時,則拋出OutOfMemoryError異常。

 

方法區(線程共享):

  被所有線程共享的一塊內存區域。

  用於存儲已被虛擬機加載的類信息,常量,靜態變量等。

  這個區域的內存回收目標主要針對常量池的回收和對類型的卸載。

  當方法區無法滿足內存分配需求時,則拋出OutOfMemoryError異常。

  在HotSpot虛擬機中,用永久代來實現方法區,將GC分代收集擴展至方法區,但是這樣容易遇到內存溢出的問題。

  JDK1.7中,已經把放在永久代的字符串常量池移到堆中。

  JDK1.8撤銷永久代,引入元空間。

 

運行時常量池:

  是方法區的一部分,用於存放編譯期生成的各種字面量和符號引用

  當常量池無法再申請到內存時,則拋出OutOfMemoryError異常。

 

直接內存:

  不是運行時數據區的一部分,但也可能拋出OutOfMemoryError異常。

  在JDK1.4中新加入的NOI類,引入了一種基於通道與緩沖區的I/O方式,它可以使用Native函數直接分配堆外內存,

然后通過一個存儲在Java堆中的DirectByteBuffer對象作為這塊內存的引用進行操作。


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM