深入理解JAVA虛擬機之運行時數據區

程序計數器

  • 極小的一塊內存空間,可以看做線程所執行的字節碼的行號指示器。
  • 線程私有 每個線程都擁有一個獨立的程序計數器。每個線程之間的計數器互相不影響。
  • 如果在執行的是一個java方法,那麼計數器記錄的是正在執行的虛擬機的字節碼指令的地址;如果執行的native方法,這個計數器值則爲空。
  • 這個區域在java虛擬機規範中 表明了不會出現 OutOfMemoryError情況

java虛擬機棧

  • java虛擬機棧 也是線程私有的,生命週期和線程相同。
  • 描述了java方法執行的內存模型,每個方法對應一個一個棧幀。
  • 棧幀
    • 局部變量表

      • 存放了各種基本數據類型、對象引用類型,它不同於對象的本身,可能是一個指向對象起始地址的引用指針。
      • 64位長度的long 和double 佔用兩個局部變量空間(slot),其餘的數據類型只佔用1個。
      • 局部變量表所需的內存空間,在編譯期間完成分配。當進入一個方法需要幀中分配多大的局部變量空間是完全確定的,運行期間不會改變局部變量表的大小。
    • 操作數棧

    • 動態鏈接

    • 方法出口

    • 一些附加信息

  • 如果棧的深度大於虛擬機棧的深度 會拋出StackOverflowError異常。如果虛擬機棧可以動態擴展的話,如果擴展的時候無法申請到足夠的內存,就會拋出OutofMemoryError異常

本地方法棧

  • 存儲結構和虛擬機棧一樣,作用也一樣。
  • 區別是 虛擬機棧是爲java方法服務,而本地方法棧則爲Native方法服務
  • 本地方法棧也會拋出StackOverflowError 和OutofMemoryError 異常

java堆(heap)

  • 線程共享的區域,由虛擬機啓動時創建。
  • 存放對象實例,幾乎所有的對象實例都在這裏分配內存。
  • java堆是垃圾收集器管理的主要區域,因此也稱GC堆。
  • java堆分爲新生代、老年代。
  • 新生代
    • Eden空間,From Survivor空間 To Survivor空間。

方法區(永久代)

  • 和java堆一樣 是線程共享的內存區域。
  • 存儲JVM 加載的類信息,常量,靜態變量。
  • 又稱元空間

運行時常量池

  • 屬於方法區的一部分。
  • 存放編譯器生成的各種字面量和符號引用,在類加載後進入方法區的運行時常量池存放。
  • 會有 OOM異常

直接內存

  • 並不屬於JVM運行時數據區的一部分,也不是JVM規範定義的內存
  • 也會導致OOM 異常
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章