Java運行時數據區域

一、程序計數器(Program Counter Register)

  1. 一塊較小的內存空間,可看做是當前線程所執行的字節碼的行號指示器。
  2. 在java多線程中,每條線程都有一個獨立的程序計數器,各條線程之間的計數器互不影響,獨立存儲。(線程私有的內存)
  3. 如果線程執行的是java方法,則程序計數器記錄的是正在執行的虛擬機字節碼指令的地址;如果線程執行的是Native方法,這個計數器值則爲空。
  4. 該內存區域是java虛擬機規範中唯一沒有規定OutOfMemoryError情況的區域。

二、虛擬機棧(VM Stack)

  1. 描述Java方法執行的內存模型:每個方法被執行的時候都會同時創建一個棧幀(用於存儲局部變量表、操作樹棧、動態鏈接、方法出口等信息)
  2. 每一個方法被調用直至執行完成,就對應着一個棧幀在虛擬機中從入棧到出棧的過程。
  3. 局部變量表:基本數據類型、對象引用(可能是指向對象起始地址的引用指針、可能是指向一個代表對象的句柄或者其他與此對象相關的位置)和returnAddress類型(指向了一條字節碼指令的地址);該表所需的內存空間在編譯期間完成分配,在運行期間不改變。
  4. 64位的long和double類型會佔用2個局部變量空間(Slot),其餘基本數據類型佔用1個。
  5. 該區域引起的兩個異常:一是如果線程請求的棧深度大於虛擬機所允許的深度,將跑出StackOverflowError異常;一是如果虛擬機棧可以動態擴展,當擴展時無法申請到足夠的內存時會拋出OutOfMemoryError異常

三、本地方法棧(Native Method Stacks)

  1. 同虛擬機棧類似,當本地方法棧是爲虛擬機使用到的Native方法服務。
  2. 有些虛擬機(如 Sun HotSpot虛擬機)直接將本地方法棧和虛擬機棧合二爲一。
  3. 同樣會拋出StackOverflowError和OutOfMemoryError異常。

四、堆(Heap,GC Heap)

  1. 被所有線程所共享,在虛擬機啓動時就被創建。
  2. 唯一目的:存放對象實例,幾乎所有的對象實例和數組都在堆上分配(現在不絕對,因爲JIT編譯器的發展和逃逸分析技術的成熟)。
  3. 可能劃分出多個線程私有的分配緩衝區(Thread Local Allocation Buffer,TLAB).
  4. 可處在物理上不連續的內存空間中,只要邏輯上是連續的就行。
  5. 堆無法再擴展時,跑出OutOfMemoryError異常。

五、方法區(Method Area)

  1. 被所有線程所共享,在虛擬機啓動時被創建。
  2. 用於存儲已被虛擬機加載的類信息、常量、靜態變量、即時編譯器編譯後的代碼等數據。
  3. 有時候被稱爲“永久代”。
  4. 當方法區無法滿足內存分配需求時,將拋出OutOfMemoryError異常。

六、運行時常量池(Runtime Constant Pool)

  1. 方法區的一部分。
  2. Class文件中有類的版本、字段、方法、接口、常量池等信息,其中常量池用於存儲編譯器後生成的各種字面量和符號引用,這部分內容將在類載入後存放到運行時常量池。
  3. 可在運行時將新的常量加入常量池中,如String的intern()方法。
  4. 當常量池無法再申請到內存時會拋出OutOfMemoryError異常。

七、直接內存(Direct Memory)

  1. 並不是虛擬機運行時數據區的一部分,也不是java虛擬機規範中定義的內存區域,但是這部分內存也被頻繁使用。
  2. JDK1.4中加入的NIO類,引入一種基於通道(Channel)與緩衝區的I/O方式,它可以使用Native函數庫直接分配堆外內存,然後通過一個存儲在java堆裏面的DirectByteBuffer對象作爲這塊內存的引用進行操作。

發佈了19 篇原創文章 · 獲贊 6 · 訪問量 3萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章