JVM
幫助指令代碼(字節(jié)碼)與底層進行(操作系統(tǒng)平臺和執(zhí)行指令并管理資源的硬件體系結(jié)構(gòu))交互。對于字節(jié)碼來說,它能夠模擬機器的寄存器弦追、堆棧等等裙椭,它是“一個真實機器有效躏哩、獨立的復制品。
- 輸入:類文件格式的文件揉燃,即 *.class文件
- 輸出:底層平臺可以執(zhí)行的最終指令扫尺,如,二進制文件
- JDK炊汤、JRE:JRE是我們安裝運行Java程序的最基本軟件正驻。它和Java類庫以及運行Java程序所需要的其他組件一起夠成了JVM的一個實現(xiàn)弊攘。JDK(Java開發(fā)工具)是JRE的超集。
類加載器
每一個在JRE上運行的Java程序都會創(chuàng)建一個JVM實例姑曙。編譯后的Java類文件和其他被依賴的類文件會被加載到運行環(huán)境中襟交。這一步由類加載器協(xié)助完成。
當運行一個JVM示例時伤靠,系統(tǒng)將分配給它一塊內(nèi)存區(qū)域(這塊內(nèi)存區(qū)域的大小可以設置的)捣域,這一內(nèi)存區(qū)域由JVM自己來管理。
分出來的這一塊就稱為運行數(shù)據(jù)區(qū)域宴合。運行數(shù)據(jù)區(qū)域可以劃分為6大塊:Java棧焕梅、程序計數(shù)寄存器(PC寄存器)、本地方法棧(Native Method Stack)卦洽、Java堆贞言、方法區(qū)域、運行常量池(Runtime Constant Pool)阀蒂。前面3各區(qū)域(PC寄存器该窗、Java棧、本地方法棧)是每個線程獨自擁有的脂新,后三者則是整個JVM實例中的所有線程共有的挪捕。
- PC計數(shù)器:每一個線程都擁有一個PC計數(shù)器,當線程啟動(start)時争便,PC計數(shù)器被創(chuàng)建级零,這個計數(shù)器存放當前正在被執(zhí)行的字節(jié)碼指令(JVM指令)的地址。
- Java棧:同樣的滞乙,Java棧也是每個線程單獨擁有奏纪,線程啟動時創(chuàng)建。這個棧中存放著一系列的棧幀(Stack Frame)斩启,JVM只能進行壓入(Push)和彈出(Pop)棧幀這兩種操作序调。每當調(diào)用一個方法時,JVM就往棧里壓入一個棧幀兔簇,方法結(jié)束返回時彈出棧幀发绢。基本類型的實例int a 等在這里垄琐,int[] a在這里的指向堆實例的引用边酒。
每個棧幀包含三個部分:本地變量數(shù)組,操作數(shù)棧狸窘,方法所屬類的常量池引用墩朦。
-
本地方法棧:當程序通過JNI(Java Native Interface)調(diào)用本地方法(如C或者C++代碼)時,就根據(jù)本地方法的語言類型建立相應的棧翻擒。
本地方法棧 - 方法區(qū)域:方法區(qū)域是一個JVM實例中的所有線程共享的氓涣,當啟動一個JVM實例時牛哺,方法區(qū)域被創(chuàng)建。它用于存運行放常量池劳吠、有關(guān)域和方法的信息引润、靜態(tài)變量、類和方法的字節(jié)碼赴背。
-
運行常量池:這個區(qū)域存放類和接口的常量椰拒,除此之外,它還存放方法和域的所有引用凰荚。當一個方法或者域被引用的時候,JVM就通過運行常量池中的這些引用來查找方法和域在內(nèi)存中的的實際地址褒脯。
方法區(qū)域和運行常量池 - 堆:堆中存放的是程序創(chuàng)建的對象或者實例便瑟。這個區(qū)域?qū)VM的性能影響很大。垃圾回收機制處理的正是這一塊內(nèi)存區(qū)域番川。
執(zhí)行引擎
類加載器將字節(jié)碼載入內(nèi)存之后到涂,執(zhí)行引擎以Java 字節(jié)碼指令為單元,讀取Java字節(jié)碼颁督。將字節(jié)碼轉(zhuǎn)化成平臺相關(guān)的機器碼践啄。這個過程可以由解釋器來執(zhí)行,也可以由即時編譯器(JIT Compiler)來完成沉御。