JVM, 中文名是java虛擬機, 正如它的名字, 是一個虛擬機器,來模擬通用的物理機。 JVM是一個標準,一套規范, 規定了.class文件在其內部運行的相關標準和規范。 及其相關的內部構成。 比如:所有的JVM都是基于棧結構的運行方式。那么不符合這種要求的,不算是JVM, 如Android中所使用的Dalvik 虛擬機就不能稱作是JAVA 虛擬機, 因為它是基于寄存器(最新的Android系統據說已經放棄了Dalvik VM, 而是使用ART)。
JVM相關的產品有很多, 通常最有名的莫過于現在Oracle公司所有的HotSpot 虛擬機。因此, 這里討論的都是HotSpot虛擬機, 如果沒有特別說明。
被java編譯器(不僅限于, 還有其他任何的可以編輯成為.class的編譯器)編譯過的.class文件(可能是以jar、war、jsp等形式), 經過類加載器加載 、 驗證、準備、解析、初始化之后, 才可以被使用?;镜倪^程如下:
加載: 首先,通過一個類的全類名來獲取此類的二進制字節流。其次,將類中所代表的靜態存儲結構轉換為運行時數據結構, 最后,生成一個代表加載的類的java.lang.Class對象, 作為方法區這個類的所有數據的訪問入口。加載完成之后, 虛擬機外部的二進制靜態數據結構就轉換成了虛擬機所需要的結構存儲在方法區中(至于如何轉換, 則由具體虛擬機自己定義實現), 而所生成的Class對象, 則存放在方法區中, 用來作為程序訪問方法區中數據的外部接口。驗證:其目的就是保證加載進來的.class文件不會危害到虛擬機本身, 且內容符合當前虛擬機規范要求。主要驗證的內容大致有:文件格式、元數據驗證、字節碼驗證、符號引用驗證。其中文件格式驗證, 主要確保符合class文件格式規范(如文本后綴為.class的文件將驗證不通過), 以及主次版本號, 驗證是否當前JVM可以處理等。元數據驗證,主要驗證編譯后的字節碼描述信息是否符合java語法規范。字節碼驗證, 其最為復雜, 主要通過控制流和數據流確定語義是否合法、符合邏輯。符號引用驗證,可以看做是除自身以外(常量池中各種引用符號)的信息匹配校驗,如通過持有的引用能否找到對應的實例。準備:正式為類變量分配內存,并設置類變量的初始值。這些變量都會在方法區中進行分配。解析:將常量池內的符號引用替換為直接引用的過程。主要針對類或接口、字段、類方法、接口方法、方法類型、方法句柄等。初始化:加載的最后階段, 程序真正運行的開始。方法區:和java堆相同, 線程共享區域, 用來存儲已被虛擬機加載的類信息, 常量、靜態變量、即時編譯器編譯后的代碼等數據。有人稱作此方法區為“永久帶”, 本質上不等價,只是HotSpot VM將GC分代收集擴展到了方法區,這樣HotSpot的垃圾收集器管理方法區和管理java堆一樣(優點:不用專門為方法區寫一套垃圾收集器, 缺點:容易導致內存溢出)。官方現在擁也有放棄永久帶并改為采用Native Memory來實現方法區的計劃,目前已經發布的JDK7中的HotSpot中, 已經將原本放在方法區中的字符串常量池移出了。
運行時常量池:是方法區的一部分。Class文件中除了有類的版本、字段、方法、接口等描述外,還有一項就是常量池, 用于存放編譯期間生成的各種字面量和符號引用 ,這部分內容在類加載后進入方法區的運行時常量池中存放。
新聞熱點
疑難解答