JVM 從入門到精通(五)JVM運行時數據區——程序計數器(PC寄存器)

寫在前面:我是「雲祁」,一枚熱愛技術、會寫詩的大數據開發猿。暱稱來源於王安石詩中一句 [ 雲之祁祁,或雨於淵 ] ,甚是喜歡。


寫博客一方面是對自己學習的一點點總結及記錄,另一方面則是希望能夠幫助更多對大數據感興趣的朋友。如果你也對 數據中臺、數據建模、數據分析以及Flink/Spark/Hadoop/數倉開發 感興趣,可以關注我的動態 https://blog.csdn.net/BeiisBei ,讓我們一起挖掘數據的價值~


每天都要進步一點點,生命不是要超越別人,而是要超越自己! (ง •_•)ง

一、PC Register 介紹

JVM中的程序計數寄存器(Program Counter Register)中,Register的命名源於CPU的寄存器,寄存器存儲指令相關的現場信息。CPU只有把數據裝載到寄存器才能夠運行。JVM中的PC寄存器是對物理PC寄存器的一種抽象模擬。

在這裏插入圖片描述
作用:

PC寄存器用來存儲指令向下一條指令的地址,也即將要執行的指令代碼。由執行引擎讀取下一條指令。

在這裏插入圖片描述

  • 它是一塊很小的內存空間,幾乎可以忽略不記。也是運行速度最快的存儲區域。

  • 在JVM規範中,每個線程都有它自己的程序計數器,是線程私有的,生命週期與線程的生命週期保持一致。

  • 任何時間一個線程都只有一個方法在執行,也就是所謂的當前方法。程序計數器會存儲當前線程正在執行的Java方法的JVM指令地址;或者,如果是在執行native方法,則是未指定值(undefned)。

  • 它是程序控制流的指示器,分支、循環、跳轉、異常處理、線程恢復等基礎功能都需要依賴這個計數器來完成。

  • 字節碼解釋器工作時就是通過改變這個計數器的值來選取下一條需要執行的字節碼指令。

  • 它是唯一一個在Java虛擬機規範中沒有規定任何OutOtMemoryError情況的區域。

二、舉例說明

利用javap -v xxx.class反編譯字節碼文件,查看指令等信息。

在這裏插入圖片描述

三、兩個常見問題

  1. 使用PC寄存器存儲字節碼指令地址有什麼用呢(爲什麼使用PC寄存器記錄當前線程的執行地址呢)
    (1)多線程宏觀上是並行(多個事件在同一時刻同時發生)的,但實際上是併發交替執行的
    (2)因爲CPU需要不停的切換各個線程,這時候切換回來以後,就得知道接着從哪開始繼續執行
    (3)JVM的字節碼解釋器就需要通過改變PC寄存器的值來明確下一條應該執行什麼樣的字節碼指令
    所以,衆多線程在併發執行過程中,任何一個確定的時刻,一個處理器或者多核處理器中的一個內核,只會執行某個線程中的一條指令。這樣必然導致經常中斷或恢復,如何保證分毫無差呢?每個線程在創建後,都會產生自己的程序計數器和棧幀,程序計數器在各個線程之間互不影響。

  2. PC寄存器爲什麼會設定爲線程私有?
    (1)我們都知道所謂的多線程在一個特定的時間段內只會執行其中某一個線程的方法,CPU會不停滴做任務切換,這樣必然會導致經常中斷或恢復,如何保證分毫無差呢?
    (2)爲了能夠準確地記錄各個線程正在執行的當前字節碼指令地址,最好的辦法自然是爲每一個線程都分配一個PC寄存器,這樣一來各個線程之間便可以進行獨立計算,從而不會出現相互干擾的情況。

  3. CPU時間片
    CPU 時間片即CPU分配給各個程序的時間,每個線程被分配一個時間段,稱作它的時間片。在宏觀上:我們可以同時打開多個應用程序,每個程序並行不悖,同時運行。但是在微觀上:由於只有一個CPU,一次只能處理程序要求的一部分,如何處理公平,一種方法就是引入時間片,每個程序輪流執行。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章