JVM運行時數據區--程序計數器


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

一個線程對應一個 JVM Stack。JVM Stack 中包含一組 Stack Frame。當 JVM 調用一個 Java 方法時,它從對應類的類型信息中得到此方法的局部變量區和操作數棧的大小,並據此分配棧幀內存,然后壓入 JVM 棧中。

在活動線程中,只有位於棧頂的棧幀才是有效的,稱為當前棧幀,與這個棧幀相關聯的方法稱為當前方法。

程序計數寄存器作用

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

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

2.在jvm規范中,每個線程都有它自己的程序計數器,是線程私有的,生命周期與線程的生命周期保持一致

3.任何時間一個線程都只有一個方法在執行,也就是所謂的當前方法。程序計數器會存儲當前線程正在執行的java方法的JVM指令地址;或者,如果實在執行native方法,則是未指定值(undefined),因為程序計數器不負責本地方法棧

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

5.字節碼解釋器工作時就是通過改變這個計數器的值來選取嚇一跳需要執行的字節碼指令

6.它是唯一一個在java虛擬機規范中沒有規定任何OOM(Out Of Memery)情況的區域,而且沒有垃圾回收

 

代碼示例

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

 

PC寄存器面試常問

1. 使用PC寄存器存儲字節碼指令地址有什么用呢(為什么使用PC寄存器記錄當前線程的執行地址呢)
(1)多線程宏觀上是並行(多個事件在同一時刻同時發生)的,但實際上是並發交替執行的
(2)因為CPU需要不停的切換各個線程,這時候切換回來以后,就得知道接着從哪開始繼續執行
(3)JVM的字節碼解釋器就需要通過改變PC寄存器的值來明確下一條應該執行什么樣的字節碼指令
所以,眾多線程在並發執行過程中,任何一個確定的時刻,一個處理器或者多核處理器中的一個內核,只會執行某個線程中的一條指令。這樣必然導致經常中斷或恢復,如何保證分毫無差呢?每個線程在創建后,都會產生自己的程序計數器和棧幀,程序計數器在各個線程之間互不影響。
2. PC寄存器為什么會設定為線程私有?
(1)我們都知道所謂的多線程在一個特定的時間段內只會執行其中某一個線程的方法,CPU會不停滴做任務切換,這樣必然會導致經常中斷或恢復,如何保證分毫無差呢?
(2)為了能夠准確地記錄各個線程正在執行的當前字節碼指令地址,最好的辦法自然是 為每一個線程都分配一個PC寄存器,這樣一來各個線程之間便可以進行獨立計算,從而不會出現相互干擾的情況。




免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM