jvm运行时数据区是干啥的?CPU切换线程会不会突然忘记程序执行到哪一步了
目錄
還是那張JVM總體圖
線程
程序計數器(PC寄存器)
使用PC寄存器存儲字節碼指令地址有什么用呢?為什么使用PC寄存器記錄當前線程的執行地址呢?
PC寄存器為什么會被設定為線程私有?
CPU時間片
還是那張JVM總體圖
? ? 內存是非常重要的系統資源,是硬盤和CPU的中間倉庫及橋梁,承載著操作系統和應用程序的實時運行。JVM內存布局規定了Java在運行過程中內存申請、分配、管理的策略,保證了JVM的高效穩定運行。不同的JVM對于內存的劃分方式和管理機制存在著部分差異。結合JVM虛擬機規范,來探討一下經典的JVM內存布局。
? ? Java虛擬機定義了若干種程序運行期間會使用到的運行時數據區,其中有一些會隨著虛擬機啟動而創建,隨著虛擬機退出而銷毀。另外一些則是與線程一一對應的,這些與線程對應的數據區域會隨著線程開始和結束而創建和銷毀。
? ? 灰色的為單獨線程私有的,紅色的為多個線程共享的。即:
? ? 每個線程:獨立包括程序計數器、棧、本地棧。線程間共享:堆、堆外內存(永久代或元空間、代碼緩存)。
線程
? ? 1.線程是一個程序里的運行單元。JVM允許一個應用有多個線程并行的執行。
? ? 2.在HotSpot JVM里,每個線程都與操作系統的本地線程直接映射。當一個Java線程準備好執行以后,此時一個操作系統的本地線程也同時創建,Java線程執行終止后,本地線程也會回收。
? ? 3.操作系統負責所有線程的安排調度到任何一個可用的CPU上。一旦本地線程初始化成功,它就會調用Java線程中的run()方法。
? ? 4.守護線程也叫精靈線程, 當程序只剩下 守護線程的時候 程序就會退出。守護線程的作用 類似在后臺靜默執行,比如JVM的垃圾回收機制, 這個就是一個 守護線程。 而非守護線程則不會。
? ? 如果使用jconsole或者是任何一個調試工具,都能看到在后臺有許多線程在運行。這些后臺線程不包括調用main方法的main線程以及所有這個main線程自己創建的線程。
? ? 這些主要的后臺系統線程在Hotspot JVM里主要是以下幾個:
? ? 1.虛擬機線程:這種線程的操作是需要JVM達到安全點才會出現。這些操作必須在不同的線程中發生的原因是他們都需要JVM達到安全點,這樣堆才不會變化。這種線程的執行類型包括“stop-hte-world”的垃圾收集,線程棧收集,線程掛起以及偏向鎖撤銷。
? ? 2.周期任務線程:這種線程是時間周期事件的體現(比如中斷),他們一般用于周期性操作的調度執行。
? ? 3.GC線程:這種線程對在JVM里不同種類的垃圾收集行為提供了支持。
? ? 4.編譯線程:這種線程在運行時會將字節碼編譯成到本地代碼。
? ? 5.信號調度線程:這種線程接收信號并發送給JVM,在它內部通過調用適當的方法進行處理。
程序計數器(PC寄存器)
? ? JVM中的程序計數寄存器(program Counter Register)中,Register的命名源于CPU的寄存器,寄存器存儲指令相關的現場信息。CPU只有把數據裝載到寄存器才能夠運行。
? ? 這里,并非廣義上所指的物理寄存器,或許將其翻譯為PC計數器(或指令計數器)會更加貼切(也成為程序鉤子),并且也不容易引起一些不必要的誤會。JVM中的PC寄存器是對物理PC寄存器的一種抽象模擬。
作用:
? ? PC寄存器用來存儲指向下一條指令的地址,也即將要執行的指令代碼。由執行引擎讀取下一條指令。
? ? 它是一塊很小的內存空間,幾乎可以忽略不計,也是運行速度最快的存儲區域。
? ? 在JVM規范中,每個線程都有它自己的程序計數器,是線程私有的,生命周期與線程的生命周期保持一致。
? ? 任何時間一個線程都只有一個方法在執行,也就是所謂的當前方法。程序計數器會存儲當前線程正在執行的Java方法的JVM指令地址;或者,如果是在執行native方法,則是未指定值(undefined)。
? ? 它是程序控制流的指示器,分支、循環、跳轉、異常處理、線程恢復等基礎功能都需要依賴這個計數器來完成。
? ? 字節碼解釋器工作時就是通過改變這個計數器的值來選取下一條需要執行的字節碼指令。
? ? 它是唯一一個在Java虛擬機規范中沒有規定任何OutOfMemoryError情況的區域。
使用PC寄存器存儲字節碼指令地址有什么用呢?為什么使用PC寄存器記錄當前線程的執行地址呢?
? ? 因為CPU需要不停的切換各個線程,這時候切換回來以后,就得知道接著從哪開始繼續執行。
? ? JVM的字節碼解釋器就需要通過改變PC寄存器的值來明確下一條應該執行什么樣的字節碼指令。
PC寄存器為什么會被設定為線程私有?
? ? 我們都知道所謂的多線程在一個特定的時間段內只會執行其中某一個線程的方法,CPU會不停地做任務切換,這樣必然導致經常中斷或恢復,如何保證分毫無差呢?為了能夠準確地記錄各個線程正在執行的當前字節碼指令地址,最好的辦法自然是為每一個線程都分配一個PC寄存器,這樣一來各個線程之間便可以進行獨立計算,從而不會出現相互干擾的情況。
? ? 由于CPU時間片輪限制,眾多線程在并發執行過程中,任何一個確定的時刻,一個處理器或者多核處理器中的一個內核,只會執行某個線程的一條指令。
? ? 這樣必然導致經常中斷或恢復,如何保證分毫無差呢?每個線程在創建后,都會產生自己的程序計數器和棧幀,程序計數器在各個線程之間互不影響。
CPU時間片
? ? CPU時間片即CPU分配給各個程序的時間,每個線程被分配一個時間段,稱作它的時間片。
? ? 在宏觀上:我們可以同時打開多個應用程序,每個程序并行不悖,同時運行。
? ? 在微觀上:由于只有一個CPU,一次只能處理程序要求的一部分,如何處理公平,一種方法就是引入時間片,每個程序輪流執行。
總結
以上是生活随笔為你收集整理的jvm运行时数据区是干啥的?CPU切换线程会不会突然忘记程序执行到哪一步了的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: java类是如何加载的?不知道class
- 下一篇: 你只知道JVM栈,知不知道栈帧、局部变量