【轉】Jvm工作原理

來源:互聯網
上載者:User

標籤:

一、         JVM的生命週期

1.       JVM執行個體對應了一個獨立啟動並執行java程式它是進程層級

a)     啟動。啟動一個Java程式時,一個JVM執行個體就產生了,任何一個擁有public static void main(String[] args)函數的class都可以作為JVM執行個體啟動並執行起點

b)     運行。main()作為該程式初始線程的起點,任何其他線程均由該線程啟動。JVM內部有兩種線程:守護線程和非守護線程,main()屬於非守護線程,守護線程通常由JVM自己使用,java程式也可以標明自己建立的線程是守護線程

c)     消亡。當程式中的所有非守護線程都終止時,JVM才退出;若安全管理器允許,程式也可以使用Runtime類或者System.exit()來退出

2.       JVM執行引擎執行個體則對應了屬於使用者運行程式的線程它是線程層級的

 

二、         JVM的體繫結構

 

 

1.       類裝載器(ClassLoader)(用來裝載.class檔案)

2.       執行引擎(執行位元組碼,或者執行本地方法)

3.       運行時資料區(方法區、堆、java棧、PC寄存器、本地方法棧)

 

三、         JVM類載入器

JVM整個類載入過程的步驟:

1.       裝載

裝載過程負責找到二進位位元組碼並載入至JVM中,JVM通過類名、類所在的包名通過ClassLoader來完成類的載入,同樣,也採用以上三個元素來標識一個被載入了的類:類名+

包名+ClassLoader執行個體ID。

2.       連結

連結過程負責對二進位位元組碼的格式進行校正、初始化裝載類中的靜態變數以及解析類中調用的介面、類。

完成校正後,JVM初始化類中的靜態變數,並將其值賦為預設值。

最後對類中的所有屬性、方法進行驗證,以確保其需要調用的屬性、方法存在,以及具備應的許可權(例如public、private域許可權等),會造成NoSuchMethodError、NoSuchFieldError等錯誤資訊。

3.       初始化

初始化過程即為執行類中的靜態初始化代碼、構造器代碼以及靜態屬性的初始化,在四種情況下初始化過程會被觸發執行:

調用了new;

反射調用了類中的方法;

子類調用了初始化;

JVM啟動過程中指定的初始化類。

 

JVM類載入順序:

JVM兩種類裝載器包括:啟動類裝載器和使用者自訂類裝載器。

啟動類裝載器是JVM實現的一部分;

使用者自訂類裝載器則是Java程式的一部分,必須是ClassLoader類的子類。

JVM裝載順序:

                Jvm啟動時,由Bootstrap向User-Defined方向載入類;

                應用進行ClassLoader時,由User-Defined向Bootstrap方向尋找並載入類;

1.       Bootstrap ClassLoader

這是JVM的根ClassLoader,它是用C++實現的,JVM啟動時初始化此ClassLoader,並由此ClassLoader完成$JAVA_HOME中jre/lib/rt.jar(Sun JDK的實現)中所有class檔案的載入,這個jar中包含了java規範定義的所有介面以及實現。

2.       Extension ClassLoader

JVM用此classloader來載入擴充功能的一些jar包。

3.       System ClassLoader

JVM用此classloader來載入啟動參數中指定的Classpath中的jar包以及目錄,在Sun JDK中ClassLoader對應的類名為AppClassLoader。

4.       User-Defined ClassLoader

User-DefinedClassLoader是Java開發人員繼承ClassLoader抽象類別自行實現的ClassLoader,基於自訂的ClassLoader可用於載入非Classpath中的jar以及目錄。

 

ClassLoader抽象類別的幾個關鍵方法:

(1)       loadClass

此方法負責載入指定名字的類,ClassLoader的實現方法為先從已經載入的類中尋找,如沒有則繼續從parent ClassLoader中尋找,如仍然沒找到,則從System ClassLoader中尋找,最後再調用findClass方法來尋找,如要改變類的載入順序,則可覆蓋此方法

(2)       findLoadedClass

此方法負責從當前ClassLoader執行個體對象的緩衝中尋找已載入的類,調用的為native的方法。

(3)       findClass

此方法直接拋出ClassNotFoundException,因此需要通過覆蓋loadClass或此方法來以自訂的方式載入相應的類。

(4)       findSystemClass

此方法負責從System ClassLoader中尋找類,如未找到,則繼續從Bootstrap ClassLoader中尋找,如仍然為找到,則返回null。

(5)       defineClass

此方法負責將二進位的位元組碼轉換為Class對象

(6)       resolveClass

此方法負責完成Class對象的連結,如已連結過,則會直接返回。

 

四、         JVM執行引擎

在執行方法時JVM提供了四種指令來執行:

(1)invokestatic:調用類的static方法

(2)invokevirtual:調用對象執行個體的方法

(3)invokeinterface:將屬性定義為介面來進行調用

(4)invokespecial:JVM對於初始化對象(Java構造器的方法為:<init>)以及調用對象執行個體中的私人方法時。

 

主要的執行技術有:

解釋,即時編譯,自適應最佳化、晶片級直接執行

(1)解釋屬於第一代JVM,

(2)即時編譯JIT屬於第二代JVM,

(3)自適應最佳化(目前Sun的HotspotJVM採用這種技術)則吸取第一代JVM和第二代

JVM的經驗,採用兩者結合的方式

開始對所有的代碼都採取解釋執行的方式,並監視代碼執行情況,然後對那些經常調用的方法啟動一個後台線程,將其編譯為本地代碼,並進行最佳化。若方法不再頻繁使用,則取消編譯過的代碼,仍對其進行解釋執行。

 

五、         JVM運行時資料區

第一塊:PC寄存器

PC寄存器是用於儲存每個線程下一步將執行的JVM指令,如該方法為native的,則PC寄存器中不儲存任何資訊。

第二塊:JVM棧

JVM棧是線程私人的,每個線程建立的同時都會建立JVM棧,JVM棧中存放的為當前線程中局部基本類型的變數(java中定義的八種基本類型:boolean、char、byte、short、int、long、float、double)、部分的返回結果以及Stack Frame,非基本類型的對象在JVM棧上僅存放一個指向堆上的地址

第三塊:堆(Heap)

它是JVM用來儲存物件執行個體以及數組值的地區,可以認為Java中所有通過new建立的對象的記憶體都在此分配,Heap中的對象的記憶體需要等待GC進行回收。

(1)       堆是JVM中所有線程共用的,因此在其上進行對象記憶體的分配均需要進行加鎖,這也導致了new對象的開銷是比較大的

(2)       Sun Hotspot JVM為了提升對象記憶體配置的效率,對於所建立的線程都會分配一塊獨立的空間TLAB(Thread Local Allocation Buffer),其大小由JVM根據啟動並執行情況計算而得,在TLAB上指派至時不需要加鎖,因此JVM在給線程的對象分配記憶體時會盡量的在TLAB上分配,在這種情況下JVM中指派至記憶體的效能和C基本是一樣高效的,但如果對象過大的話則仍然是直接使用堆空間分配

(3)       TLAB僅作用於新生代的Eden Space,因此在編寫Java程式時,通常多個小的對象比大的對象分配起來更加高效。

第四塊:方法地區(Method Area)

(1)在Sun JDK中這塊地區對應的為PermanetGeneration,又稱為持久代。

(2)方法地區存放了所載入的類的資訊(名稱、修飾符等)、類中的靜態變數、類中定義為final類型的常量、類中的Field資訊、類中的方法資訊,當開發人員在程式中通過Class

對象中的getName、isInterface等方法來擷取資訊時,這些資料都來源於方法地區,同時方法地區也是全域共用的,在一定的條件下它也會被GC,當方法地區需要使用的記憶體超過其允許的大小時,會拋出OutOfMemory的錯誤資訊。

第五塊:運行時常量池(Runtime Constant Pool)

存放的為類中的固定的常量資訊、方法和Field的引用資訊等,其空間從方法地區中分配。

第六塊:本地方法堆棧(Native Method Stacks)

JVM採用本地方法堆棧來支援native方法的執行,此地區用於儲存每個native方法調用的狀態。

 

六、         JVM記憶體回收

GC的基本原理:將記憶體中不再被使用的對象進行回收,GC中用於回收的方法稱為收集器,由於GC需要消耗一些資源和時間,Java在對對象的生命週期特徵進行分析後,按照新生代、舊生代的方式來對對象進行收集,以儘可能的縮短GC對應用造成的暫停

(1)對新生代的對象的收集稱為minor GC;

(2)對舊生代的對象的收集稱為Full GC;

(3)程式中主動調用System.gc()強制執行的GC為Full GC。

不同的對象參考型別, GC會採用不同的方法進行回收,JVM對象的引用分為了四種類型:

(1)強引用:預設情況下,對象採用的均為強引用(這個對象的執行個體沒有其他對象引用,GC時才會被回收)

(2)軟引用:軟引用是Java中提供的一種比較適合於緩衝情境的應用(只有在記憶體不夠用的情況下才會被GC)

(3)弱引用:在GC時一定會被GC回收

(4)虛引用:由於虛引用只是用來得知對象是否被GC

 

連結:http://www.open-open.com/lib/view/open1408453806147.html

http://www.cnblogs.com/sunada2005/p/3577799.html

【轉】Jvm工作原理

相關文章

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.