1. 程式人生 > 實用技巧 >20200730 尚矽谷 JVM 04 - 程式計數器

20200730 尚矽谷 JVM 04 - 程式計數器

04 - 程式計數器(PC 暫存器)

1 - PC Register 介紹

JVM 中的程式計數暫存器( Program Counter Register )中, Register 的命名源於 CPU 的暫存器,暫存器儲存指令相關的現場資訊。 CPU 只有把資料裝載到暫存器才能夠執行。

這裡,並非是廣義上所指的物理暫存器,或許將其翻譯為 PC 計數器(或指令計數器)會更加貼切(也稱為程式鉤子),並且也不容易引起一些不必要的誤會。 JVM 中的 PC 暫存器是對物理 PC 暫存器的一種抽象模擬

作用: PC 暫存器用來儲存指向下一條令的地址也即將要執行的指令程式碼。由執行引擎讀取下一條指令。

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

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

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

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

  • 位元組碼直譯器工作時就是通過改變這個計數器的值來選取下一條需要執行的位元組碼指令。

  • 它是唯一一個在 Java 虛擬機器規範中沒有規定任何 OutOfMemoryError

    情況的區域。

2 - 舉例說明

3 - 兩個常見問題

使用 PC 存器儲存位元組碼指令地址有什麼用呢?為什麼使用 PC 暫存器記錄當前執行緒的執行地此呢?

因為 CPU 需要不停的切換各個執行緒,這時候切換回來以後,就得知道接著從哪開始繼續執行。

JVM 的位元組碼直譯器就需要通過改變 PC 暫存器的值來明確下一條應該執行什麼樣的位元組碼指令。

PC 暫存器為什麼會被設定為執行緒私有?

我們都知道所謂的多執行緒在一個特定的時間段內只會執行其中某一個執行緒的方法, CPU 會不停地做任務切換,這樣必然導致經常中斷或恢復,如何保證分毫無差呢?為了能夠準確地記錄各個執行緒正在執行的當前位元組碼指令地址,最好的辦法自然是為每一個執行緒都分配一個 PC 暫存器

,這樣一來各個執行緒之間便可以進行獨立計算,從而不會出現相互干擾的情況。

由於 CPU 時間片輪限制,眾多執行緒在併發執行過程中,任何一個確定的時刻,一個處理器或者多核處理器中的一個核心,只會執行某個執行緒中的一條指令。

這樣必然導致經常中斷或恢復,如何保證分毫無差呢?每個執行緒在建立後,都會產生自己的程式計數器和幀,程式計數器在各個執行緒之間互不影響。

CPU 時間片

CPU 時間片即 CPU 分配給各個程式的時間,每個執行緒被分配一個時間段,稱作它的時間片

在巨集觀上:我們可以同時開啟多個應用程式,每個程式並行不悖,同時執行。

但在微觀上:由於只有一個 CPU ,一次只能處理程式要求的一部分,如何處理公平,一種方法就是引入時間片,每個程式輪流執行。

理解序列、並行、併發
  • 序列:即順序執行
  • 併發(Concurrent),在作業系統中,是指一個時間段中有幾個程式都處於已啟動執行到執行完畢之間,且這幾個程式都是在同一個處理機上執行。
  • 並行(Parallel),當系統有一個以上CPU時,當一個CPU執行一個程序時,另一個CPU可以執行另一個程序,兩個程序互不搶佔CPU資源,可以同時進行,這種方式我們稱之為並行(Parallel)。其實決定並行的因素不是CPU的數量,而是CPU的核心數量,比如一個CPU多個核也可以並行。