一、程序計數器的大體
JVM中的程序計數寄存器中(Program Counter Register),Register 的命名源於CPU的寄存器,寄存器存儲指令相關的現場信息。
CPU只有把數據裝載到寄存器才能夠運行。
這里,並非是廣義上所指的物理寄存器,或許將其翻譯為PC計數器(或指令計數器)會更加貼切,並且也不容易引起一些不必要的誤會。
JVM中的PC寄存器是對物理PC寄存器的一種抽象模擬。
二、作用
PC寄存器用來存儲指向下一條指令的地址,也即將要執行的指令代碼。由執行引擎讀取下一條指令。
特點是線程私有的,不會存在內存溢出。
三、程序計數器的介紹
它是一塊很小的內存空間,幾乎可以忽略不記。也是運行速度最快的存儲區域。
在JVM規范中,每個線程都有它自己的程序計數器,是線程私有的,生命周期與線程的生命周期保持一致。
任何時間一個線程都有一個方法在執行,也就是所謂的當前方法。程序計數器會存儲當前線程正在執行的JAVA方法的JVM指令地址;
或者,如果在執行native方法,則是未指定值(undefned)
他是程序控制流的指示燈,分支,循環,跳轉,異常處理,線程恢復等基礎功能都需要依賴這個計數器來完成。
字節碼解釋器工作時就是通過改變這個計數器的值來選取下一條需要執行的字節碼指令。
它是唯一 一個在java虛擬機規范中沒有規定任何OutOtMemoryError情況的區域。
四、程序計數器常見問題
1、使用PC寄存器存儲字節碼指令地址有什么用呢?為什么使用PC寄存器記錄當前線程的執行地址呢?
因為CPU需要不停的切換各個線程,這時候切換回來之后,就得知道接着從哪個開始繼續執行。
JVM的字節碼解釋器就需要通過改變PC寄存器的值來明確下一條應該執行什么樣的字節碼指令
2、PC寄存器為什么會被設定為線程私有的?
我們都知道所謂的多線程在一個特定的時間段內只會執行其中某一個線程的方法,CPU會不停地做任務切換
這樣必然會導致經常中斷和恢復,如何保證分毫無差呢?
為了准確地記錄各個線程正在執行的當前字節碼指令地址,最好的方法自然是為每一個線程都分配一個PC寄存器,
這樣一來各個線程之間便可以進行獨立計算,從而不會出現相互干擾的情況。
由於CPU時間片輪限制,眾多線程在並發執行過程中,任何一個確定的時刻,一個處理器或者多核處理器中的一個內核,
只會執行某一個線程中的一條指令。
這樣必然導致經常會中斷和恢復,如何保證分毫無差呢?每個線程在創建后,都會產生自己的程序計數器和棧幀,程序計數器在各個線程之間互不影響。
3、關於線程在JVM中的說明
在Hotspot JVM里,每個線程都與操作系統的本地線程直接映射。
當一個Java線程准備好執行以后,此時一個操作系統的本地線程也同時創建.Java線程執行終止后,本地線程也會被回收。
操作系統負責所有線程的安全調度到任何一個可用的CPU上,一旦本地線程初始化完畢,他就會調用java線程中的run方法。
4、Native Interface 本地接口
本地接口的作用是融合不同的語言為java所用,它的初衷是融合C/C++程序,java誕生的時候是C/C++橫行的時候,要想立足,
必須調用C/C++程序,於是就在內存中開辟了一塊區域處理標記native的代碼,他的具體做法是Native Method Stack中登記native方法,
在Execution Engine執行時加載native libraies。
目前該方法的使用的越來越少了,除非是與硬件有關的應用,比如通過Java程序驅動打印機或者Java系統管理生產設備,在企業級應用中已經比較少見。
因為現在的異構領域間的通信很發達,比如可以使用Socket通信,也可以使用Web Service等等,不多做介紹
五、CPU時間片
CPU時間片即CPU分配各個程序的時間,每個線程被分配一個時間段,稱作它的時間片。
在宏觀上,我們可以同時打開多個應用程序,每個程序並行不干擾,同時運行。
但在微觀上,由於只有一個CPU,一次只能處理程序要求的一部分,如何處理公平,一種方法就是引入時間片,每個程序輪流執行。
引用地址:https://blog.csdn.net/TZ845195485/article/details/108095745