JVM學習總結(一)運行時數據區

《深刻Java虛擬機》這本書買了有一段時間了,當時看的時候就只是看,並無邊看邊總結啥的,最後發現到腦子裏面的根本所剩無幾了。如今開始要好好概括總結地再學習一遍。java

運行時數據區域

JVM在執行Java程序的過程當中會把它所管理的內存劃分爲若干個不一樣的數據區域。所管理的內存包括如下幾個運行時數據區域數組

輸入圖片說明

  1. 程序計數器
  • 做用:記錄當前線程所執行的字節碼的行號。字節碼解釋器工做時就是經過改變這個計數器的值來選取下一條須要執行的字節碼指令
  • 意義:JVM的多線程是經過線程輪流切換並分配CPU時間方式來實現的,所以,爲了線程切換後能恢復到正確的指定位置,每條線程丟都須要一個獨立的程序計數器
  • 存儲內容 : 若線程正執行的是一個Java方法時,程序計數器中記錄的是正在執行的線程的虛擬機字節碼指令的地址 若線程正執行的是一個本地方法時,程序計數器中的值爲空
  • 可能發生的異常: 程序計數器是惟一一個Java虛擬機規範中沒有規定任何OutOfMemoryError狀況的區域
  1. Java虛擬機棧
  • 做用:描述Java方法執行的內存模型,每一個方法執行的時候都會建立一個棧幀,棧幀裏面存儲了局部變量表、操做數棧、動態連接、方法出口等信息
  • 意義:方法從開始執行到執行結束,就對應着一個棧幀在Java虛擬機棧中入棧到出棧的過程
  • 存儲內容: 局部變量表(編譯期間可知的各類基本數據類型、引用類型和指向一條字節碼指令的returnAddress類型)、操做數棧、動態連接、方法出口等信息 值得注意的是:局部變量表所需的內存空間在編譯期間完成分配。在方法運行的階段是不會改變局部變量表的大小的
  • 可能發生的異常: StackOverflowError異常:若是線程請求的棧深度大於虛擬機所容許的深度,將拋出該異常 OutOfMemoryError異常:若是虛擬機棧能夠動態擴展(當前大部分的Java虛擬機均可以動態擴展,只不過虛擬機規範中也容許固定長度的虛擬機棧)若是擴展時沒法申請到足夠的內存,就會拋出該異常
  1. 本地方法棧
  • 做用:爲JVM所調用到的Native即本地方法服務 ps:Sun HotSpot虛擬機 直接把本地方法棧和虛擬機棧合二爲一
  • 可能發生的異常:同虛擬機棧,存在StackOverflowError異常和OutOfMemoryError異常
  1. Java堆
  • 做用:分配全部的對象實例以及數組,但隨着即時編譯(JIT)器的發展與逃逸分析技術逐漸成熟,棧上分配、標量替換優化技術使得對象都在對上分配變得不那麼絕對
  • 意義:Java堆是Java虛擬機所管理的內存中最大的一塊,被全部線程共享,在JVM啓動時建立。Java堆是垃圾收集器管理的主要區域,Java堆能夠細分爲:新生代(Young Generation)、老年代(Old Generation)、永久代(Permanent Generation);新生代再細緻一點能夠分爲Eden空間、From Survivor空間、To Survivor空間。若是配置-XX:+/-UseTLAB,每一個線程在Java堆中預先分配一小塊內存,稱爲本地線程分配緩衝(Thread Local Allocation Buffer, TLAB)
  • 存儲內容: 存放對象實例及數組(建立數組時,建立動做由字節碼指令newarray觸發,虛擬機自動生成一個爲java.lang.Object的子類的類,這個類中實現了數組中應有的屬性和方法,能夠直接訪問的爲public類型的length屬性和clone()方法),幾乎全部的對象實例都在這裏進行分配。堆能夠處於物理上不連續的內存空間,只要邏輯上是連續的就能夠
  • 可能發生的異常:若是堆中沒有內存完成實例分配,而且堆也沒法再拓展(堆能夠是固定大小的,拓展可經過-Xms和-Xmx參數控制)時,將會拋出OutOfMemoryError異常
  1. 方法區
  • 做用:用於存儲運行時常量池、已被虛擬機加載的類信息、常量、靜態變量、即時編譯器編譯後的代碼等數據
  • 意義:對運行時常量池、常量、靜態變量等數據作出了規定
  • 存儲內容:運行時常量池(具備動態性)、已被虛擬機加載的類信息、常量、靜態變量、即時編譯器編譯後的代碼等數據
  • 可能發生的異常:當方法區沒法知足內存分配需求的時候拋出OutOfMemoryError異常

運行時常量池多線程

運行時常量池是方法區的一部分。Class文件中出了有類的版本、字段、方法、接口等描述信息外,還有一項信息是常量池,用於存放編譯期間生成的各類字面量和符號引用,這部份內容將在類加載後進入方法區的運行時常量池存放學習

jdk六、jdk七、jdk8對於方法區的設計不一樣優化

  • 運行時常量池在JDK1.6及以前版本的JVM中是方法區的一部分,而在HotSpot虛擬機中方法區放在了」永久代」。因此運行時常量池也是在永久代的
  • 可是JDK1.7及以後版本的JVM已經將運行時常量池從方法區中移了出來,在Java 堆(Heap)中開闢了一塊區域存放運行時常量池
  • 而在JDK1.8中,已經完全沒有了永久代,將方法區直接放在一個與堆不相連的本地內存區域,這個區域被叫作元空間
相關文章
相關標籤/搜索