JVM筆記1:Java內存區域

運行時數據區域

       在Java程序運行時,Java虛擬機將其管理的內存劃分爲不同的運行時數據區域:
在這裏插入圖片描述

程序計數器

       如果對計算機組成有所瞭解的話,應該很容易理解程序計數器(PC),可以認爲其中的數據就是下一條指令的地址(字節碼行號),在當前指令執行完畢後,JVM會根據PC中的數據找到下一條指令。除此以外,在當前線程被中斷後恢復時,JVM也要根據PC中的值恢復現場。該內存區域並沒有規定任何OOM的情況。

虛擬機棧

       在一個線程中,每當開始執行一個普通的Java方法時,虛擬機會爲該線程創建一個棧幀(Stack Frame),並將其放入該線程所屬的虛擬機棧中。當該方法執行完成後,對應的棧幀就會出棧。
       棧幀中保存了方法的局部變量表、操作數棧、動態連接、方法出口等信息。

  • 局部變量表:存放方法參數和方法內部定義的局部變量。該表的容量以變量槽(Variable Slot)爲單位,一個變量槽能夠存放一個boolean、btye、char、short、int、float、reference或returnAddress類型的數據,而一個變量槽的實際內存大小取決於處理器、操作系統和虛擬機的實現。
  • 操作數棧:用於執行過程中保存操作數和結果。如做算數運算時存放操作數,或者在調用其他方法時存放參數。
  • 動態連接:運行時常量池中有一部分方法的引用在運行時才轉化爲直接引用,這部分的引用就稱爲動態連接。、
  • 方法出口:也叫方法返回地址。即該方法在執行完畢後,下一條應該執行的指令的地址。

       該區域有兩種可能的異常狀況:

  • 如果線程請求的棧深度大於虛擬機所允許的深度,拋出StackOverFlow異常
  • 如果虛擬機棧容量可以動態擴展,當棧擴展時無法申請到足夠的內存會拋出OutOfMemeoryError異常

本地方法棧

       本地方法棧的作用與虛擬機棧很相似,區別在於當執行的方法是本地方法時,棧幀會被壓入本地方法棧。甚至有的虛擬機在實現時直接將其與虛擬機棧合併。

Java堆

       Java堆用來存放幾乎所有的對象實例,所有線程共享這一區域。垃圾收集器(Garbage Collector)管理的就是Java堆中的對象。

       Java堆可以被實現爲固定大小,也可以是可擴展的。如果Java堆的空間已不夠用,並且也無法擴展時,JVM會拋出OutOfMemoryError異常。

方法區

       方法區用於存儲被虛擬機加載的類型信息、常量、靜態變量、即時編譯器變異後的代碼緩存等數據,所有線程共享這一區域。

       其中,類型信息包含:類的元信息(類的完整名稱,修飾符,父類,接口等),類型的常量池,字段信息,方法信息,類變量,指向加載器的引用,指向Class實例的引用等。

       如果方法區無法滿足新的內存分配需求時,將拋出OutOfMemoryError異常。

運行時常量池

       運行時常量池是方法區的一部分,用於存放編譯時期產生的各種字面量(常量)與符號引用。這些常量在編譯時期由編譯器生成在Class文件中的常量池表中,JVM在運行時將其複製到運行時常量池中。

總結

數據區域 存放內容 產生時期/銷燬時期 可擴展 異常狀況
程序計數器 下一條指令“地址” 線程生成/線程銷燬 不可擴展
虛擬機棧 棧幀 線程生成/線程銷燬 允許擴展 StackOverflowError, OutOfMemoryError
Java堆 對象實例 虛擬機啓動/虛擬機關閉 允許擴展 OutOfMemoryError
方法區(包括運行時常量池) 已加載的類信息,靜態變量等(常量保存在運行時常量池中) 虛擬機啓動/虛擬機關閉 允許擴展 OutOfMemoryError
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章