JVM筆記--如果你寫JVM,最需要考慮的重要結構是什么?


開局一張圖,前面已經從每一部分解析過JVM的內存結構了,現在按照順序來分析:

整體上來看:類文件從類加載子系統,加載完成之后,主要存放在方法區(JRockit和H9沒有方法區,這里指的是HotSpot)。運行時的數據主要是存放在運行時數據區,代碼的解釋編譯優化以及垃圾收集,都是在執行引擎中。本地方法是指Native方法,也就是C/C++編寫的方法。

類加載子系統

類文件首先需要經過類加載子系統,進行加載,進類信息等加載到運行時數據區。

在類加載子系統中有以下三個階段操作:

  • 加載
  • 鏈接
  • 初始化

其中加載的時候,有三種類加載器:

  • Bootstrap ClassLoader:引導類加載器,主要加載JDK里面的核心類
  • Extension ClassLoader:拓展類加載器
  • Application ClassLoader:應用加載器

而鏈接也分為3個階段,主要是:

  • 驗證
  • 鏈接
  • 解析

運行時數據區

經過類加載子系統加載之后,進入運行時數據區,運行時區域主要分為:

  • 線程私有:
    • 程序計數器:Program Count Register,線程私有,沒有垃圾回收
    • 虛擬機棧:VM Stack,線程私有,沒有垃圾回收
    • 本地方法棧:Native Method Stack,線程私有,沒有垃圾回收
  • 線程共享:
    • 方法區:Method Area,以HotSpot為例,JDK1.8后元空間取代方法區,有垃圾回收。
    • 堆:Heap,垃圾回收最重要的地方。

虛擬機棧,每一個線程有一份,每一個線程的虛擬機棧里面,存放的是一個個棧幀,每一個棧幀表示一個方法調用。

PC寄存器,同樣是每一個線程有一份,不同線程之間執行到何處,互不干擾。

執行引擎

執行引擎里面可以逐行解釋執行,也可以編譯成機器指令直接執行,主要包括:

  • 解釋器
  • 即時編譯器:即時編譯器中包括了中間代碼生成器,代碼優化器,目標代碼生成器等。
  • 垃圾收集器

解釋器,需要逐行解釋執行,效率低下。譬如:如果循環兩千次,循環體很大,每次執行都需要解釋執行。

JIT 編譯器,除了可以直接全部即時編譯,還可以統計出那些代碼執行頻率比較高,這部分代碼就是熱點代碼,這種技術叫做熱點代碼探測技術JIT 編譯器會將熱點代碼,提前編譯成為機器指令,放在方法區緩存起來,下次執行到的時候,不需要解釋執行,而是直接運行機器指令。

即時編譯器的執行效率很高,為什么不將它全部提前編譯好緩存起來呢?

  • 全部提前編譯,首次啟動響應速度慢,會有卡頓的感覺,因為編譯需要大量時間。(主要原因)
  • 緩存代碼,需要放在方法區,占用內存空間,容易溢出。
  • 翻譯成為機器指令,則這部分緩存的 CodeCache 是不能夠直接跨平台,因為不同環境的機器指令是不大一樣的,只能每次運行前就全部編譯。

如果需要寫一個虛擬機,那么需要考慮的重要兩部分是:類加載子系統執行引擎類加載子系統負責將類信息按照規定,加載到運行時數據區,而執行引擎主要負責對代碼解釋執行或者編譯成二進制緩存起來,進行執行。

【作者簡介】
秦懷,公眾號【秦懷雜貨店】作者,技術之路不在一時,山高水長,縱使緩慢,馳而不息。個人寫作方向:Java源碼解析,JDBC,Mybatis,Spring,redis,分布式,劍指Offer,LeetCode等,認真寫好每一篇文章,不喜歡標題黨,不喜歡花里胡哨,大多寫系列文章,不能保證我寫的都完全正確,但是我保證所寫的均經過實踐或者查找資料。遺漏或者錯誤之處,還望指正。

2020年我寫了什么?

開源刷題筆記

平日時間寶貴,只能使用晚上以及周末時間學習寫作,關注我,我們一起成長吧~


免責聲明!

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



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