JVM用寄存器實(shí)現(xiàn)程序計(jì)數(shù)
1.PC 寄存器介紹
- JVM中的程序計(jì)數(shù)寄存器(Program Counter Register),Register的命名源于CPU的寄存器,寄存器存儲指令相關(guān)的現(xiàn)場信息。CPU只有把數(shù)據(jù)裝載到寄存器才能夠運(yùn)行。
- 這里,并非是廣義上所指的物理寄存器,或許將其翻譯為PC計(jì)數(shù)器(或指令計(jì)數(shù)器)會更加貼切(也稱為程序鉤子),并且也不容易引起一些不必要的誤會。JVM中的PC寄存器是對物理PC寄存器的一種抽象模擬。
- 它是一塊很小的內(nèi)存空間,幾乎可以忽略不記。也是運(yùn)行速度最快的存儲區(qū)域。
- 在JVM規(guī)范中,每個線程都有它自己的程序計(jì)數(shù)器,是線程私有的,生命周期與線程的生命周期保持一致。
- 任何時(shí)間一個線程都只有一個方法在執(zhí)行,也就是所謂的當(dāng)前方法。程序計(jì)數(shù)器會存儲當(dāng)前線程正在執(zhí)行的Java方法的JVM指令地址;或者,如果是在執(zhí)行native方法,則是未指定值(undefined)。
- 它是程序控制流的指示器,分支、循環(huán)、跳轉(zhuǎn)、異常處理、線程恢復(fù)等基礎(chǔ)功能都需要依賴這個計(jì)數(shù)器來完成
- 字節(jié)碼解釋器工作時(shí)就是通過改變這個計(jì)數(shù)器的值來選取下一條需要執(zhí)行的字節(jié)碼指令。
- 它是唯一一個在Java虛擬機(jī)規(guī)范中沒有規(guī)定任何OutofMemoryError情況的區(qū)域。
2.PC 寄存器的作用
PC寄存器用來存儲指向下一條指令的地址,也就是即將要執(zhí)行的指令代碼。由執(zhí)行引擎讀取下一條指令,并執(zhí)行該指令。
3.代碼示例
public class PCRegisterTest { public static void main(String[] args) { int i = 10; int j = 20; int k = i + j; String s = "abc"; System.out.println(i); System.out.println(k); } }
使用反編譯:javap -v PCRegisterTest.class
左邊的數(shù)字代表指令地址 (偏移地址),即 PC 寄存器中可能存儲的值,然后執(zhí)行引擎讀取 PC 寄存器中的值,并執(zhí)行該指令
4.兩個常見面試題
使用 PC寄存器 存儲字節(jié)碼指令地址有什么用呢?
或者問 為什么使用 PC寄存器 來記錄當(dāng)前線程的執(zhí)行地址呢?
- 因?yàn)榫€程是一個個的順序執(zhí)行流,CPU需要不停的切換各個線程,這時(shí)候切換回來以后,就得知道接著從哪開始繼續(xù)執(zhí)行
- JVM的字節(jié)碼解釋器就需要通過改變PC寄存器的值來明確下一條應(yīng)該執(zhí)行什么樣的字節(jié)碼指令
PC寄存器為什么被設(shè)定為私有的?
- 我們都知道所謂的多線程在一個特定的時(shí)間段內(nèi)只會執(zhí)行其中某一個線程的方法,CPU會不停地做任務(wù)切換,這樣必然導(dǎo)致經(jīng)常中斷或恢復(fù),如何保證分毫無差呢?
- 為了能夠準(zhǔn)確地記錄各個線程正在執(zhí)行的當(dāng)前字節(jié)碼指令地址,最好的辦法自然是為每一個線程都分配一個PC寄存器,這樣一來各個線程之間便可以進(jìn)行獨(dú)立計(jì)算,從而不會出現(xiàn)相互干擾的情況。
- 由于CPU時(shí)間片輪限制,眾多線程在并發(fā)執(zhí)行過程中,任何一個確定的時(shí)刻,一個處理器或者多核處理器中的一個內(nèi)核,只會執(zhí)行某個線程中的一條指令。
- 這樣必然導(dǎo)致經(jīng)常中斷或恢復(fù),如何保證分毫無差呢?每個線程在創(chuàng)建后,都會產(chǎn)生自己的程序計(jì)數(shù)器和棧幀,程序計(jì)數(shù)器在各個線程之間互不影響。
5.CPU時(shí)間片
- CPU時(shí)間片即CPU分配給各個程序的時(shí)間,每個線程被分配一個時(shí)間段,稱作它的時(shí)間片。
- 在宏觀上:我們可以同時(shí)打開多個應(yīng)用程序,每個程序并行不悖,同時(shí)運(yùn)行。
- 但在微觀上:由于只有一個CPU,一次只能處理程序要求的一部分,如何處理公平,一種方法就是引入時(shí)間片,每個程序輪流執(zhí)行。
到此這篇關(guān)于JVM用寄存器實(shí)現(xiàn)程序計(jì)數(shù)的文章就介紹到這了,更多相關(guān)JVM程序計(jì)數(shù)器內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
Java實(shí)現(xiàn)多個數(shù)組間的排列組合
這篇文章主要為大家詳細(xì)介紹了Java實(shí)現(xiàn)多個數(shù)組間的排列組合,具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2018-02-02SpringCloud使用feign調(diào)用錯誤的問題
這篇文章主要介紹了SpringCloud使用feign調(diào)用錯誤的問題,具有很好的參考價(jià)值,希望對大家有所幫助。如有錯誤或未考慮完全的地方,望不吝賜教2023-06-06剖析Spring WebFlux反應(yīng)式編程設(shè)計(jì)及工作原理
這篇文章主要為大家介紹了Spring WebFlux反應(yīng)式編程模型工作原理的剖析,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步早日升職加薪2022-02-02Java設(shè)計(jì)模式之Builder建造者模式
這篇文章主要為大家詳細(xì)介紹了Java設(shè)計(jì)模式之Builder建造者模式的相關(guān)資料,具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2018-03-03java返回前端實(shí)體類json數(shù)據(jù)時(shí)忽略某個屬性方法
這篇文章主要給大家介紹了關(guān)于java返回前端實(shí)體類json數(shù)據(jù)時(shí)忽略某個屬性的相關(guān)資料,文中通過示例代碼介紹的非常詳細(xì),需要的朋友可以參考下2023-08-08springsecurity記住我登錄時(shí)訪問無權(quán)限接口跳轉(zhuǎn)登錄界面的處理方案
這篇文章主要介紹了springsecurity記住我登錄時(shí)訪問無權(quán)限接口跳轉(zhuǎn)登錄界面的處理方案,本文給大家介紹的非常詳細(xì),對大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友參考下吧2024-02-02