jvm運行時數據區及線程

語言: CN / TW / HK

我正在參加「掘金·啟航計劃」

運行時數據區(Runtime Data Area):

calss文件通過類加載器加載(load、link、initialize)到內存當中,這個內存就是屬於運行時數據區,當然不只是class,運行時數據區主要包括:元空間(Metaspace)、程序計數器(Program counter Register)、本地方法棧(Native Method Stack)、虛擬機棧(JVM Stack)、堆(Heap)。如下圖:

image.png

運行時數據區與內存

  1. 內存是非常重要的系統資源,是硬盤和CPU的中間倉庫及橋樑,承載着操作系統和應用程序的實時運行。JVM內存佈局規定了Java在運行過程中內存申請、分配、管理的策略,保證了JVM的高效穩定運行。不同的JVM對於內存的劃分方式和管理機制存在着部分差異。結合JVM虛擬機規範,來探討一下經典的JVM內存佈局。
  2. 我們通過磁盤或者網絡IO得到的數據,都需要先加載到內存中,然後CPU從內存中獲取數據進行讀取,也就是説內存充當了CPU和磁盤之間的橋樑

下圖為阿里jdk1.8的運行時數據區劃分圖:

image.png

線程的內存空間

  1. Java虛擬機定義了若干種程序運行期間會使用到的運行時數據區:其中有一些會隨着虛擬機啟動而創建,隨着虛擬機退出而銷燬。另外一些則是與線程一一對應的,這些與線程對應的數據區域會隨着線程開始和結束而創建和銷燬。

  2. 灰色的為單獨線程私有的,紅色的為多個線程共享的。即:

    • 線程獨有:獨立包括程序計數器、棧、本地方法棧
    • 線程間共享:堆、堆外內存(永久代或元空間、代碼緩存)

如下圖:

image.png

Runtime類

每個JVM只有一個Runtime實例。即為運行時環境,相當於內存結構的中間的那個框框:運行時環境。

image.png

線程

JVM 線程

  1. 線程是一個程序裏的運行單元。JVM允許一個應用有多個線程並行的執行

  2. 在Hotspot JVM裏,每個線程都與操作系統的本地線程直接映射

    • 當一個Java線程準備好執行以後,此時一個操作系統的本地線程也同時創建。Java線程執行終止後,本地線程也會回收
  3. 操作系統負責將線程安排調度到任何一個可用的CPU上。一旦本地線程初始化成功,它就會調用Java線程中的run()方法

JVM 系統線程

  • 如果你使用jconsole或者是任何一個調試工具,都能看到在後台有許多線程在運行。這些後台線程不包括調用public static void main(String[])的main線程以及所有這個main線程自己創建的線程。
  • 這些主要的後台系統線程在Hotspot JVM裏主要是以下幾個:

  • 虛擬機線程:這種線程的操作是需要JVM達到安全點才會出現。這些操作必須在不同的線程中發生的原因是他們都需要JVM達到安全點,這樣堆才不會變化。這種線程的執行類型括”stop-the-world”的垃圾收集,線程棧收集,線程掛起以及偏向鎖撤銷

  • 週期任務線程:這種線程是時間週期事件的體現(比如中斷),他們一般用於週期性操作的調度執行
  • GC線程:這種線程對在JVM裏不同種類的垃圾收集行為提供了支持
  • 編譯線程:這種線程在運行時會將字節碼編譯成到本地代碼
  • 信號調度線程:這種線程接收信號併發送給JVM,在它內部通過調用適當的方法進行處理