1. JVM簡介 初識JVM JVM是Java Virtual Machine(Java虛擬機)的縮寫,JVM是一種用於計算設備的規範,它是一個虛構出來的電腦,是通過在實際的電腦上模擬模擬各種電腦功能來實現的。 Java語言的一個非常重要的特點就是與平臺的無關性。而使用Java虛擬機是實現這一 ...
1. JVM簡介
- 初識JVM
JVM是Java Virtual Machine(Java虛擬機)的縮寫,JVM是一種用於計算設備的規範,它是一個虛構出來的電腦,是通過在實際的電腦上模擬模擬各種電腦功能來實現的。
Java語言的一個非常重要的特點就是與平臺的無關性。而使用Java虛擬機是實現這一特點的關鍵。一般的高級語言如果要在不同的平臺上運行,至少需要編譯成不同的目標代碼。而引入Java語言虛擬機後,Java語言在不同平臺上運行時不需要重新編譯。Java語言使用Java虛擬機屏蔽了與具體平臺相關的信息,使得Java語言編譯程式只需生成在Java虛擬機上運行的目標代碼(位元組碼),就可以在多種平臺上不加修改地運行。Java虛擬機在執行位元組碼時,把位元組碼解釋成具體平臺上的機器指令執行。這就是Java的能夠“一次編譯,到處運行”的原因。
從編譯原理的角度來看,可以將編譯過程按照“前端+後端”的方式進行劃分。所謂的前端,就是指依賴源語言而與目標機無關,而後端則指依賴目標機而不依賴源語言。JVM的這種實現機制屬於不同機器構造統一語言的編譯程式的模式,即“同一前端+不同後端”;同樣的道理,還有“不同前端+同一後端”,即同一機器生成不同語言的編譯程式的模式,如.NET平臺
JVM是Java程式運行的容器,但是他同時也是操作系統的一個進程,因此他也有他自己的運行的生命周期,也有自己的代碼和數據空間。一個運行時的JVM實例負責運行一個Java程式。當啟動一個Java程式,則一個虛擬機實例也就誕生了,當程式關閉退出,虛擬機實例也就隨之消亡,每個Java程式都運行於各自的虛擬機實例中。
每個JVM都有兩種機制,一個是裝載具有合適名稱的類(類或是介面),叫做類裝載子系統;另外的一個負責執行包含在已裝載的類或介面中的指令,叫做運行引擎。類裝載子系統除了要定位和導入二進位class文件外,還必須負責驗證被導入類的正確性,為類變數分配並初始化記憶體,以及幫助解析符號引用。
不容忽視的是運行時數據區,又叫虛擬機記憶體或者Java記憶體,虛擬機運行時需要從整個電腦記憶體劃分一塊記憶體區域存儲許多東西。例如:位元組碼、從已裝載的class文件中得到的其他信息、程式創建的對象、傳遞給方法的參數,返回值、局部變數等等。Java虛擬機定義了若幹種程式運行時所使用的運行時數據區,有些是隨著Java虛擬機的啟動而創建的,同時,隨著虛擬機的關閉而銷毀,而有些則是與線程一一對應。
- 認識Java記憶體
上面已經說到,運行時數據區即Java記憶體,根據存儲數據的不同,Java記憶體通常被劃分為5個區域:程式計數器(Program Count Register)、本地方法棧(Native Stack)、方法區(Methon Area)、棧(Stack)、堆(Heap)。下麵針對每部分的功能進行簡單介紹:
程式計數器/PC寄存器:又叫程式寄存器。JVM支持多個線程同時運行,當每一個新線程被創建時,它都將得到它自己的PC寄存器(程式計數器)。如果線程正在執行的是一個Java方法(非native),那麼PC寄存器的值將總是指向下一條將被執行的指令,如果方法是 native的,程式計數器寄存器的值不會被定義。簡單來說,程式寄存器可以看做當前線程所執行的位元組碼的信號指示器。
棧:又叫堆棧。JVM為每個新創建的線程都分配一個棧。
本地方法棧:存儲本地方方法的調用狀態。
方法區:當虛擬機裝載一個class文件時,它會從這個class文件包含的二進位數據中解析類型信息,然後把這些類型信息(包括類信息、常量、靜態變數等)放到方法區中。常量池存放在方法區中。
堆:堆是Java虛擬機所管理的記憶體中最大的一塊,是被所有線程共用的一塊記憶體區域。在此區域的唯一目的就是存放對象實例,幾乎所有的對象實例都是在這裡分配記憶體,但是這個對象的引用卻是在棧中分配。因此,執行String s = new String(“s”)時,需要從兩個地方分配記憶體:在堆中為String對象分配記憶體,在棧中為引用(這個堆對象的記憶體地址,即指針)分配記憶體。