日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當(dāng)前位置: 首頁(yè) > 编程资源 > 编程问答 >内容正文

编程问答

小师妹学JVM之:JVM的架构和执行过程

發(fā)布時(shí)間:2024/2/28 编程问答 38 豆豆
生活随笔 收集整理的這篇文章主要介紹了 小师妹学JVM之:JVM的架构和执行过程 小編覺得挺不錯(cuò)的,現(xiàn)在分享給大家,幫大家做個(gè)參考.

文章目錄

  • 簡(jiǎn)介
  • JVM是一種標(biāo)準(zhǔn)
  • java程序的執(zhí)行順序
  • JVM的架構(gòu)
    • 類加載系統(tǒng)
    • 運(yùn)行時(shí)數(shù)據(jù)區(qū)域
    • 執(zhí)行引擎
  • 總結(jié)

簡(jiǎn)介

JVM也叫Java Virtual Machine,它是java程序運(yùn)行的基礎(chǔ),負(fù)責(zé)將java bytecode轉(zhuǎn)換成為適合在各個(gè)不同操作系統(tǒng)中運(yùn)行的機(jī)器代碼并運(yùn)行。今天我們和小師妹一起走進(jìn)java的核心JVM,領(lǐng)略java在設(shè)計(jì)上的哲學(xué)。

JVM是一種標(biāo)準(zhǔn)

小師妹:F師兄,經(jīng)常聽到有人說(shuō)hotspot VM,這個(gè)跟JVM是什么關(guān)系?

其實(shí)吧,JVM只是一種標(biāo)準(zhǔn),就像是一種協(xié)議,只要是實(shí)現(xiàn)和滿足這種協(xié)議的都可以稱為JVM。當(dāng)然,java現(xiàn)在是Oracle公司的,所以這些所謂的JVM標(biāo)準(zhǔn)也是由Oracle來(lái)頒布的,如果你去查看Oracle的文檔,就會(huì)發(fā)現(xiàn)有一個(gè)專門的Java SE Specifications欄目,這個(gè)欄目中列出了JVM的實(shí)現(xiàn)標(biāo)準(zhǔn),最新的標(biāo)準(zhǔn)就是The Java Virtual Machine Specification, Java SE 14 Edition。

更多精彩內(nèi)容且看:

  • 區(qū)塊鏈從入門到放棄系列教程-涵蓋密碼學(xué),超級(jí)賬本,以太坊,Libra,比特幣等持續(xù)更新
  • Spring Boot 2.X系列教程:七天從無(wú)到有掌握Spring Boot-持續(xù)更新
  • Spring 5.X系列教程:滿足你對(duì)Spring5的一切想象-持續(xù)更新
  • java程序員從小工到專家成神之路(2020版)-持續(xù)更新中,附詳細(xì)文章教程

更多內(nèi)容請(qǐng)?jiān)L問www.flydean.com

既然JVM是一個(gè)標(biāo)準(zhǔn),就可能有很多種實(shí)現(xiàn)。各大公司在滿足JVM標(biāo)準(zhǔn)的基礎(chǔ)上,開發(fā)了很多個(gè)不同的版本。

下面是我在維基百科中截取到的目前各個(gè)JVM的比較:

小師妹:F師兄,大家齊心協(xié)力做一個(gè)JVM不是更好嗎?為什么分來(lái)分去的,還要重復(fù)造輪子?

有聽過Oracle和Google之間的API十年訴訟案嗎?API都不能順便用,更何況是JVM。各大廠商為了各自的利益,最終搞出了這么多個(gè)JVM的版本。

在這些JVM中,最常用的就是HotSpot JVM了,畢竟它是Oracle的親兒子,或者可以說(shuō)HotSpot JVM就是JVM的標(biāo)準(zhǔn)。

接下來(lái)就是Eclipse OpenJ9,這個(gè)是由IBM主導(dǎo)的JVM,一般只能跟IBM的產(chǎn)品一起使用的,因?yàn)橛性S可證限制。

java程序的執(zhí)行順序

為了說(shuō)明JVM的作用,我們先來(lái)回顧一下java程序的執(zhí)行順序。

  • 編寫java代碼文件比如Example.java
  • 使用java編譯器javac將源文件編譯成為Example.class文件
  • JVM加載生成的字節(jié)碼文件,將其轉(zhuǎn)換成為機(jī)器可以識(shí)別的native machine code執(zhí)行
  • JVM的架構(gòu)

    小師妹:F師兄,Java語(yǔ)言那么多特性,最后都要在JVM中運(yùn)行,JVM的架構(gòu)是不是特別復(fù)雜?好怕我聽不懂。

    其實(shí)吧,JVM可以分為三大部分,五大空間和三大引擎,要講起來(lái)也不是特別復(fù)雜,先看下面的總體的JVM架構(gòu)圖。

    從上面的圖中,我們可以看到JVM中有三大部分,分別是類加載系統(tǒng),運(yùn)行時(shí)數(shù)據(jù)區(qū)域和Execution Engine。

    類加載系統(tǒng)

    類加載系統(tǒng)分為三個(gè)階段,分別是加載,鏈接和初始化。

    加載大家都很清楚了,java中有個(gè)專門的ClassLoader來(lái)負(fù)責(zé)這個(gè)事情。除了加載Class之外,ClassLoader還可以用來(lái)加載resources。

    在JDK9之前,系統(tǒng)默認(rèn)有三個(gè)類加載器,分別是:

  • Bootstrap ClassLoader
  • 這個(gè)類加載器主要是加載 /jre/lib下面的rt.jar,并且這個(gè)類加載器是用C/C++來(lái)編寫的,并且它是后面Extension ClassLoader的父ClassLoader。
    這個(gè)類應(yīng)該在java代碼中找不到的(correct me if I am wrong!)。

  • Extension ClassLoader
  • 這個(gè)類加載器主要加載JDK的擴(kuò)展類 /jre/lib/ext,它的實(shí)現(xiàn)類是 sun.misc.Launcher$ExtClassLoader :

    static class ExtClassLoader extends URLClassLoader {private static volatile Launcher.ExtClassLoader instance;public static Launcher.ExtClassLoader getExtClassLoader() throws IOException {if (instance == null) {Class var0 = Launcher.ExtClassLoader.class;synchronized(Launcher.ExtClassLoader.class) {if (instance == null) {instance = createExtClassLoader();}}}return instance;}

    我們看下它的實(shí)現(xiàn),實(shí)際上它創(chuàng)建了一個(gè)單例模式,使用的是雙重檢查加鎖,小師妹可以考慮一下怎么使用延遲初始化占位類的方式來(lái)重新這個(gè)類。

  • System ClassLoader
  • 這個(gè)加載器是加載定義在ClassLoader中的類。它的實(shí)現(xiàn)類是sun.misc.Launcher$AppClassLoader,這個(gè)類的實(shí)現(xiàn)很長(zhǎng),這里就不完整列出來(lái)了:

    static class AppClassLoader extends URLClassLoader

    在JDK9之后,因?yàn)橐肓薐PMS模塊的概念,所以類加載器變得不一樣了,在JDK9之后還是有三個(gè)內(nèi)置的類加載器,分別是BootClassLoader,PlatformClassLoader和AppClassLoader:

    private static class BootClassLoader extends BuiltinClassLoader {BootClassLoader(URLClassPath bcp) {super(null, null, bcp);}@Overrideprotected Class<?> loadClassOrNull(String cn, boolean resolve) {return JLA.findBootstrapClassOrNull(this, cn);}}; private static class PlatformClassLoader extends BuiltinClassLoader private static class AppClassLoader extends BuiltinClassLoader

    Linking階段主要做了三件事情:

  • Verification - 主要驗(yàn)證字節(jié)碼文件的結(jié)構(gòu)的正確性,如果不正確則會(huì)報(bào)LinkageError。
  • Preparation - 負(fù)責(zé)創(chuàng)建static fields,并且初始化他們的值。
  • Resolution - 把類型的常量池中引用的類,接口,字段和方法替換為直接引用的過程。
  • Initialization階段主要是調(diào)用class的父類和自身的初始化方法,來(lái)設(shè)置變量的初始值。

    運(yùn)行時(shí)數(shù)據(jù)區(qū)域

    類加載好了,也初始化了,接下來(lái)就可以準(zhǔn)備運(yùn)行了。

    運(yùn)行的時(shí)候要為數(shù)據(jù)分配運(yùn)行空間,這就是運(yùn)行時(shí)數(shù)據(jù)區(qū)域的作用。

    運(yùn)行時(shí)數(shù)據(jù)區(qū)域又可以分為5個(gè)部分:

  • Method Area
  • 方法區(qū)是非Heap的內(nèi)存空間,主要用來(lái)存放class結(jié)構(gòu),static fields, method, method’s data 和 static fields等。方法區(qū)是在JVM啟動(dòng)的時(shí)候創(chuàng)建的,并且在所有的線程中共享。

    Run-Time Constant Pool運(yùn)行時(shí)常量池是放在方法區(qū)中的,他是class文件中constant_pool的運(yùn)行時(shí)表現(xiàn)。

    注意在JDK8之前,HotSpot JVM中對(duì)方法區(qū)的實(shí)現(xiàn)叫做持久代Perm Gen。不過在JDK8之后,Perm Gen已經(jīng)被取消了,現(xiàn)在叫做Metaspace。Metaspace并不在java虛擬機(jī)中,它使用的是本地內(nèi)存。Metaspace可以通過-XX:MaxMetaspaceSize來(lái)控制。

  • Heap Area
  • Heap Area主要存儲(chǔ)類對(duì)象和數(shù)組。垃圾回收器(GC)主要就是用來(lái)回收Heap Area中的對(duì)象的。

  • Stack Area
  • 因?yàn)槭菞5慕Y(jié)構(gòu),所以這個(gè)區(qū)域總是LIFO(Last in first out)。我們考慮一個(gè)方法的執(zhí)行,當(dāng)方法執(zhí)行的時(shí)候,就會(huì)在Stack Area中創(chuàng)建一個(gè)block,這個(gè)block中持有對(duì)本地對(duì)象和其他對(duì)象的引用。一旦方法執(zhí)行完畢,則這個(gè)block就會(huì)出棧,供其他方法訪問。

  • PC Registers
  • PC Registers主要用來(lái)對(duì)程序的執(zhí)行狀態(tài)進(jìn)行跟蹤,比如保存當(dāng)前的執(zhí)行地址,和下一步的地址等。

  • Native Methods
  • 最后一個(gè)就是本地方法區(qū)了,因?yàn)镴VM的底層很多都是由C/C++來(lái)實(shí)現(xiàn)的,這些方法的實(shí)現(xiàn)就構(gòu)成了本地方法區(qū)。

    執(zhí)行引擎

    執(zhí)行引擎主要負(fù)責(zé)將java的字節(jié)碼翻譯成機(jī)器碼然后執(zhí)行。

    先看一個(gè)java字節(jié)碼的內(nèi)在結(jié)構(gòu),大家可以隨便找一個(gè)編譯好的類,使用javap來(lái)進(jìn)行解析:

    javap -v BufferUsage

    這里不過多介紹輸出結(jié)果的含義,我們會(huì)在后面的文章中進(jìn)行詳解。

    這我們可以看到方法中都有一個(gè)Code片段,這些Code被稱為OpCode,是JVM可以理解的操作命令。

    執(zhí)行引擎中里面又有三個(gè)部分:

  • Interpreter
  • 翻譯器用來(lái)讀取上面介紹的OpCode,并將其翻譯成為機(jī)器語(yǔ)言。因?yàn)榉g器需要一個(gè)命令一個(gè)命令的翻譯字節(jié)碼,所以速度會(huì)比較慢。這就是很久很久以前Java被詬病的地方。

  • JIT (Just-In-Time) compiler
  • 為了解決Interpreter翻譯慢的問題,JDK引入了JIT,對(duì)于那些經(jīng)常使用的代碼,JIT會(huì)將這些字節(jié)碼翻譯成為機(jī)器代碼,并直接復(fù)用這些機(jī)器代碼,從而提高了執(zhí)行效率。

  • Garbage Collector
  • GC用來(lái)回收Heap Area,他是一個(gè)Daemon thread。

    總結(jié)

    本文介紹了JVM的總體架構(gòu)信息。各個(gè)部分的細(xì)節(jié)信息會(huì)在后面的系列文章中陸續(xù)講解。歡迎大家關(guān)注小師妹系列。

    本文作者:flydean程序那些事

    本文鏈接:http://www.flydean.com/jvm-all-in-one/

    本文來(lái)源:flydean的博客

    歡迎關(guān)注我的公眾號(hào):程序那些事,更多精彩等著您!

    總結(jié)

    以上是生活随笔為你收集整理的小师妹学JVM之:JVM的架构和执行过程的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問題。

    如果覺得生活随笔網(wǎng)站內(nèi)容還不錯(cuò),歡迎將生活随笔推薦給好友。