1、Java虛擬機的生命週期:java
Java虛擬機的生命週期 一個運行中的Java虛擬機有着一個清晰的任務:執行Java程序。程序開始執行時他才運行,程序結束時他就中止。你在同一臺機器上運行三個程序,就會有三個運行中的Java虛擬機。 Java虛擬機老是開始於一個main()方法,這個方法必須是公有、返回void、直接受一個字符串數組。在程序執行時,你必須給Java虛擬機指明這個包換main()方法的類名。 Main()方法是程序的起點,他被執行的線程初始化爲程序的初始線程。程序中其餘的線程都由他來啓動。Java中的線程分爲兩種:守護線程 (daemon)和普通線程(non-daemon)。守護線程是Java虛擬機本身使用的線程,好比負責垃圾收集的線程就是一個守護線程。固然,你也能夠把本身的程序設置爲守護線程。包含Main()方法的初始線程不是守護線程。 只要Java虛擬機中還有普通的線程在執行,Java虛擬機就不會中止。若是有足夠的權限,你能夠調用exit()方法終止程序。程序員
2、java虛擬機的體系結構:編程
在Java虛擬機的規範中定義了一系列的子系統、內存區域、數據類型和使用指南。這些組件構成了Java虛擬機的內部結構,他們不只僅爲Java虛擬機的實現提供了清晰的內部結構,更是嚴格規定了Java虛擬機實現的外部行爲。 每個Java虛擬機都有一個類加載器子系統(class loader subsystem),負責加載程序中的類型(類和接口),並賦予惟一的名字。每個Java虛擬機都有一個執行引擎(execution engine),負責執行被加載類中包含的指令。 程序的執行須要必定的內存空間,如字節碼、被加載類的其餘額外信息、程序中的對象、方法的參數、返回值、本地變量、處理的中間變量等等。Java虛擬機將這些信息通通保存在數據區(data areas)中。雖然每一個Java虛擬機的實現中都包含數據區,可是Java虛擬機規範對數據區的規定卻很是的抽象。許多結構上的細節部分都留給了 Java虛擬機實現者本身發揮。不一樣Java虛擬機實現上的內存結構千差萬別。一部分實現可能佔用不少內存,而其餘如下可能只佔用不多的內存;一些實現可 能會使用虛擬內存,而其餘的則不使用。這種比較精煉的Java虛擬機內存規約,可使得Java虛擬機能夠在普遍的平臺上被實現。 數據區中的一部分是整個程序共有,其餘部分被單獨的線程控制。每個Java虛擬機都包含方法區(method area)和堆(heap),他們都被整個程序共享。Java虛擬機加載並解析一個類之後,將從類文件中解析出來的信息保存與方法區中。程序執行時建立的對象都保存在堆中。當一個線程被建立時,會被分配只屬於他本身的PC寄存器「pc register」(程序計數器)和Java堆棧(Java stack)。當線程不掉用本地方法時,PC寄存器中保存線程執行的下一條指令。Java堆棧保存了一個線程調用方法時的狀態,包括本地變量、調用方法的參數、返回值、處理的中間變量。調用本地方法時的狀態保存在本地方法堆棧中(native method stacks),可能再寄存器或者其餘非平臺獨立的內存中。 Java堆棧有堆棧塊(stack frames (or frames))組成。堆棧塊包含Java方法調用的狀態。當一個線程調用一個方法時,Java虛擬機會將一個新的塊壓到Java堆棧中,當這個方法運行結束時,Java虛擬機會將對應的塊彈出並拋棄。 Java虛擬機不使用寄存器保存計算的中間結果,而是用Java堆棧在存放中間結果。這是的Java虛擬機的指令更緊湊,也更容易在一個沒有寄存器的設備上實現Java虛擬機。 數組
3、基本結構:jvm
從Java平臺的邏輯結構上來看,咱們能夠從下圖來了解JVM:編程語言
從上圖能清晰看到Java平臺包含的各個邏輯模塊,也能瞭解到JDK與JRE的區別。線程
JVM自身的物理結構指針
此圖看出jvm內存結構對象
JVM內存結構主要包括兩個子系統和兩個組件。兩個子系統分別是Classloader子系統和Executionengine(執行引擎)子系統;兩個組件分別是Runtimedataarea(運行時數據區域)組件和Nativeinterface(本地接口)組件。blog
Classloader子系統的做用:
根據給定的全限定名類名(如java.lang.Object)來裝載class文件的內容到Runtimedataarea中的methodarea(方法區域)。Java程序員能夠extendsjava.lang.ClassLoader類來寫本身的Classloader。
Executionengine子系統的做用:
執行classes中的指令。任何JVMspecification實現(JDK)的核心都是Executionengine,不一樣的JDK例如Sun的JDK和IBM的JDK好壞主要就取決於他們各自實現的Executionengine的好壞。
Nativeinterface組件:
與nativelibraries交互,是其它編程語言交互的接口。當調用native方法的時候,就進入了一個全新的而且再也不受虛擬機限制的世界,因此也很容易出現JVM沒法控制的nativeheapOutOfMemory。
RuntimeDataArea組件:
這就是咱們常說的JVM的內存了。它主要分爲五個部分——
一、Heap(堆):一個Java虛擬實例中只存在一個堆空間
二、MethodArea(方法區域):被裝載的class的信息存儲在Methodarea的內存中。當虛擬機裝載某個類型時,它使用類裝載器定位相應的class文件,而後讀入這個class文件內容並把它傳輸到虛擬機中。
三、JavaStack(java的棧):虛擬機只會直接對Javastack執行兩種操做:以幀爲單位的壓棧或出棧
四、ProgramCounter(程序計數器):每個線程都有它本身的PC寄存器,也是該線程啓動時建立的。PC寄存器的內容老是指向下一條將被執行指令的餓地址,這裏的地址能夠是一個本地指針,也能夠是在方法區中相對應於該方法起始指令的偏移量。
五、Nativemethodstack(本地方法棧):保存native方法進入區域的地址。