程序計數器 筆記記錄
- 1. 定義
- 2. 作用
- 3. 特點
- 4. 拓展理解
- 4.1 PC寄存器存儲字節碼指令地址有什么用?
- 4.2 PC寄存器為什么被設定為線程私有的?
- 4.3 為什么執行native方法時,是undefined?
學習資料來源-b站黑馬JVM& 尚硅谷JVM精講與GC調優
1. 定義
Program Counter Register 程序計數器
當執行一條指令時,首先需要根據PC中存放的指令地址,將指令由內存取到指令寄存器中,此過程稱為“取指令”。與此同時,PC中的地址或自動加1或由轉移指針給出下一條指令的地址。此后經過分析指令,執行指令。完成第一條指令的執行,而后根據PC取出第二條指令的地址,如此循環,執行每一條指令。
JVM中的程序計數寄存器(Program Counter Register)中, Register 的命名源于CPU的寄存器,寄存器存儲指令相關的現場信息。 CPU只有把數據裝載到寄存器才能夠運行。
這里,并非是廣義上所指的物理寄存器,或許將其翻譯為PC計數器(或指令計數器)會更加貼切(也稱為程序鉤子) ,并且也不容易引起一些不必要的誤會。JVM中的PC寄存器是對物理PC寄存器的一種抽象模擬。
2. 作用
可以看作是當前線程所執行的字節碼的行號指示器,用于存儲當前線程正在執行的 Java 方法的 JVM 指令地址。如果線程執行的是 Native 方法,計數器值為 null。是唯一一個在 Java 虛擬機規范中沒有規定任何 OutOfMemoryError 情況的區域,生命周期與線程相同。來源于小林coding解釋
3. 特點
- 線程私有,CPU給多個線程分配時間片,線程執行到某個位置的時候,可能時間片用完了,這時候就需要程序計數器去記錄當前運行的指令的下一條,這樣的話線程恢復后,就可以直接接著上一次執行的位置繼續執行。每個線程都有自己的程序計數器。
- 唯一一個不會出現內存溢出的部分。
● 它是一塊很小的內存空間,幾乎可以忽略不記。也是運行速度最快的存儲區域。不會隨著程序的運行需要更大的空間。
● 在JVM規范中,每個線程都有它自己的程序計數器,是線程私有的,生命周期與線程的生命周期保持一致。
4. 拓展理解
4.1 PC寄存器存儲字節碼指令地址有什么用?
使用PC寄存器存儲字節碼指令地址有什么用呢?
(為什么使用PC寄存器記錄當前線程的執行地址呢?)
因為CPU需要不停的切換各個線程,這時候切換回來以后,就得知道接著從哪開始繼續執行。
JVM的字節碼解釋器就需要通過改變PC寄存器的值來明確下一條應該執行什么樣的字節碼指令。
● 通俗解釋就是,不同的線程執行是有分配的時間片的,假設A線程執行一半時間片用完了就輪到其他線程了,其他線程可能執行完了以后,A線程這時候執行肯定要依賴程序計數器的標記在哪里繼續執行,總不能直接執行。
4.2 PC寄存器為什么被設定為線程私有的?
PC寄存器為什么會被設定為線程私有?
我們都知道所謂的多線程在一個特定的時間段內只會執行其中某一個線程的方法,CPU會不停地做任務切換,這樣必然導致經常中斷或恢復,如何保證分毫無差呢?為了能夠準確地記錄各個線程正在執行的當前字節碼指令地址,最好的辦法自然是為每一個線程都分配一個PC寄存器,這樣一來各個線程之間便可以進行獨立計算,從而不會出現相互干擾的情況。
4.3 為什么執行native方法時,是undefined?
任何時間一個線程都只有一個方法在執行,也就是所謂的當前方法。程序計數器會存儲當前線程正在執行的Java方法的JVM指令地址;或者,如果是在執行native方法,則是未指定值(undefined)。為什么?
native 本地方法是大多是通過C實現,并未編譯成需要執行的字節碼指令,所以在計數器中當然是空(undefined)。說白了,native已經出了虛擬機管控的范圍了。