1. 程式人生 > >jvm的內部體系結構淺析--轉

jvm的內部體系結構淺析--轉

跳轉 對象 裝載 基礎 數據 defined 服務 java虛擬機規範 平時

jvm全稱是Java Virtual Machine(java虛擬機)。它之所以被稱之為是“虛擬”的,就是因為它僅僅是由一個規範來定義的抽象計算機。我們平時經常使用的Sun HotSpot虛擬機只是其中一個具體的實現(另外還有BEA JRockit、IBM J9等等虛擬機)。在實際的計算機上通過軟件來實現一個虛擬計算機。與VMWare等類似軟件不同,你是看不到jvm的,它存在於內存。

當啟動一個Java程序時,一個虛擬機實例也就誕生了。當該程序關閉退出,這個虛擬機實例也就隨之消亡。如果在同一臺計算機上同時運行三個Java程序,將得到三個Java虛擬機實例。每個Java程序都運行於它自己的Java虛擬機實例中。

Java虛擬機在執行Java程序的過程中會把它所管理的內存劃分為若幹個不同的數據區域。根據《Java虛擬機規範(第2版)》的規定,Java虛擬機所管理的內存將會包括以下幾個運行時數據區域,如下圖1所示。

技術分享

圖1 Java虛擬機的內部體系結構

下面先對圖中各部分做個簡單的說明:

1.class文件:虛擬機並不關心Class的來源是什麽語言,只要它符合Java class文件格式就可以在Java虛擬機中運行。使用Java編譯器可以把Java代碼編譯為存儲字節碼的Class文件,使用JRuby等其他語言的編譯器一樣可以把程序代碼編譯成Class文件。

2.類裝載器子系統:負責查找並裝載Class 文件到內存,最終形成可以被虛擬機直接使用的Java類型。

3.方法區:在類裝載器加載class文件到內存的過程中,虛擬機會提取其中的類型信息,並將這些信息存儲到方法區。方法區用於存儲已被虛擬機加載的類信息、常量、靜態變量、即時編譯器編譯後的代碼等數據。由於所有線程都共享方法區,因此它們對方法區數據的訪問必須被設計為是線程安全的。

4.堆:存儲Java程序創建的類實例。所有線程共享,因此設計程序時也要考慮到多線程訪問對象(堆數據)的同步問題。

5.Java棧:Java棧是線程私有的。每當啟動一個新線程時,Java虛擬機都會為它分配一個Java棧。Java棧以幀為單位保存線程的運行狀態。虛擬機只會直接對Java棧執行兩種操作:以幀為單位的壓棧或出棧。當線程調用java方法時,虛擬機壓入一個新的棧幀到該線程的java棧中。當方法返回時,這個棧幀被從java棧中彈出並拋棄。一個棧幀包含一個java方法的調用狀態,它存儲有局部變量表、操作棧、動態鏈接、方法出口等信息。

6.程序計數器:一個運行中的Java程序,每當啟動一個新線程時,都會為這個新線程創建一個自己的PC(程序計數器)寄存器。程序計數器的作用可以看做是當前線程所執行的字節碼的行號指示器。字節碼解釋器工作時就是通過改變這個計數器的值來選取下一條需要執行的字節碼指令,分支、循環、跳轉、異常處理、線程恢復等基礎功能都需要依賴這個計數器來完成。如果線程正在執行的是一個Java方法,這個計數器記錄的是正在執行的虛擬機字節碼指令的地址;如果正在執行的是Natvie方法,這個計數器值則為空(Undefined)。

7.本地方法棧:本地方法棧與虛擬機棧所發揮的作用是非常相似的,其區別不過是虛擬機棧為虛擬機執行Java方法(也就是字節碼)服務,而本地方法棧則是為虛擬機使用到的Native方法服務。任何本地方法接口都會使用某種本地方法棧。當線程調用Java方法時,虛擬機會創建一個新的棧幀並壓入Java棧。然而當它調用的是本地方法時,虛擬機會保持Java棧不變,不再在線程的Java棧中壓入新的幀,虛擬機只是簡單地動態鏈接並直接調用指定的本地方法。如果某個虛擬機實現的本地方法接口是使用C連接模型的話,那麽它的本地方法棧就是C棧。

8.執行引擎:負責執行字節碼。方法的字節碼是由Java虛擬機的指令序列構成的。每一條指令包含一個單字節的操作碼,後面跟隨0個或多個操作數。執行引擎執行字節碼時,首先取得一個操作碼,如果操作碼有操作數,取得它的操作數。它執行操作碼和跟隨的操作數規定的動作,然後再取得下一個操作碼。這個執行字節碼的過程在線程完成前將一直持續。

轉 http://www.cnblogs.com/evan2012/archive/2012/05/09/2489417.html

jvm的內部體系結構淺析--轉