JVM學習筆記——運行時數據區和程序計數器

簡介

本篇包括如下內容:java

  • 運行時數據區。
  • JVM後臺線程。
  • 程序計數器。

注:本篇及之後的筆記主要針對於Hotspot虛擬機。緩存

運行時數據區

字節碼文件通過類加載子系統的處理,已經被加載進JVM中,接下來要研究的是JVM的運行時數據區。
運行時數據區:JVM在執行JAVA程序時,會把本身管理的內存分爲若干個不一樣的區域完成不一樣的功能。根據JVM規範,JVM管理內存大概分爲如下幾個部分,如圖所示:
運行時數據區.png
針對於運行時數據區的劃分,在JDK8以前和以後出現了差別。
JDK8以前,JVM管理的內存大體可劃分爲堆,虛擬機棧,本地方法棧,程序計數器,方法區。在JDK8以後,方法區轉移到了本地內存中,稱爲元數據區,上圖顯示的是JDK8以後的內存劃分了,元數據區直接存在於本地內存中。安全

運行時數據區各區域的生命週期。

運行時數據區中有的部分是隨着虛擬機啓動而建立,隨着虛擬機退出而銷燬,另一些則是與線程一一對應的,隨着線程的開始與結束從而建立與銷燬。併發

線程私有:程序計數器,虛擬機棧,本地方法棧。
線程共享:堆,堆外空間(元數據區,代碼緩存等)。

JVM後臺線程

JVM中主要的後臺線程主要包括如下幾個:測試

虛擬機線程

這種線程的操做是須要JVM達到安全點纔會出現。這種線程的執行類型包括"stop-the-world"的垃圾收集,線程棧收集,線程掛起以及偏向鎖撤銷。spa

週期任務線程

這種線程是時間週期事件的體現,通常用於週期性操做的調度執行。線程

GC線程

這種線程對在JVM裏不一樣種類的垃圾收集行爲提供支持。code

編譯線程

這種線程在運行時會將字節碼編譯成本地代碼。blog

信號調度線程

這種線程接受信號併發送給JVM,在其內部經過調用適當的方法進行處理。生命週期

程序計數器

介紹
  • JVM中的程序計數器是對物理PC寄存器的一種抽象模擬,因此又被稱爲PC寄存器。
  • 它是一塊很小的內存空間,也是運行速度最快的存儲空間。
  • JVM規範中,每一個線程都有它本身的程序計數器,是線程私有的,生命週期和線程的生命週期保持一致。
  • 任什麼時候間一個線程只有一個方法在執行,也就是所謂的當前方法。程序計數器會儲存當前線程正在執行的Java方法的JVM指令地址;若是當前執行的是本地方法,那程序計數器中存儲的則是未指定值(undefined)。
  • 是程序控制流的指示器,字節碼解釋器的工做就是經過改變這個計數器的值來選取下一條須要執行的指令的。
  • 程序計數器是惟一一個在JVM規範中沒有規定任何OOM狀況的區域。(固然也沒有GC。
做用

程序計數器用來存儲指向下一條指令的地址。由執行引擎根據地址來讀取下一條指令。

測試

測試代碼以下:

public class PCRegisterTest {

public static void main(String[] args) {
    int i = 10;
    int j = 20;
    int k = i + j;
    }
}

通過javap反編譯以後,主要內容以下:程序計數器簡圖.png
其中指令地址即是存儲在程序計數器中的,執行引擎經過讀取指令地址,來找到對應的操做指令。

爲何要用程序計數器?

由於CPU分配資源採用的是時間片輪詢方式,各個線程之間是併發執行的,各個線程可能在執行到一半的時候CPU便把資源分配給了其餘線程,此時須要程序計數器記錄當前線程執行到了哪條指令(保留現場),而後從新得到CPU資源以後能夠繼續執行,因此程序計數器是須要線程私有的。

相關文章
相關標籤/搜索