上善若水
          In general the OO style is to use a lot of little objects with a lot of little methods that give us a lot of plug points for overriding and variation. To do is to be -Nietzsche, To bei is to do -Kant, Do be do be do -Sinatra
          posts - 146,comments - 147,trackbacks - 0
          <2011年9月>
          28293031123
          45678910
          11121314151617
          18192021222324
          2526272829301
          2345678

          常用鏈接

          留言簿(4)

          隨筆分類(157)

          隨筆檔案(125)

          收藏夾(13)

          Java GC

          Java General

          NoSQL

          Tech General

          Tech Master

          最新隨筆

          搜索

          •  

          積分與排名

          • 積分 - 896276
          • 排名 - 42

          最新評論

          閱讀排行榜

          評論排行榜

          Java虛擬機體內部系結構包括class文件、類裝載子系統、運行時數據區、之行引擎、本地方法調用結構,其中運行時數據區包括方法區、堆、Java棧、程序計數器、本地方法棧等。具體結構如下圖所示(摘自Inside Java Virtual Machine):


           

          1.       class文件

          Java中,所有源文件都編譯成二進制的字節碼,然后由虛擬機裝載運行。一般這樣的字節碼是以class文件的形式存在。在運行時,由ClassLoader類(System ClassLoader or User-defined ClassLoader)找到對應的class文件,讀取其中的字節碼,然后交由虛擬機解析運行。

          class文件中,包含了定義一個類或接口的所有信息,包括類名、訪問權限、父類名、繼承的所有接口、所有字段、所有方法、方法中的代碼、屬性等信息,并且每個class文件的開頭還包含了魔術值和版本信息,魔術值用以標識當前的字節碼是合法的字節碼,版本表示生成當前字節碼的編譯器版本,從而虛擬機獲知其版本而做特定處理,如果對于虛擬機不支持的字節碼版本號拒絕加載。

          class文件中,很多信息都是以字符串的形式存放,比如對外部類成員或方法的引用,這些字符串信息在鏈接的時候由虛擬機解析。每個Java類,不管是包成員類還是內部類都會生成一個單獨的class文件,因而class文件是相對獨立的。詳細信息參考class文件格式。

           

          2.       類裝載子系統

          類裝載子系統負責查找class文件,讀取字節碼,做部分簡單的檢驗,如魔數是否正確,版本是否受支持,各種數據格式是否正確等。部分解析后的字節碼數據存放到方法區中,最后創建字節碼代表的類或接口的Class實例。

          Java中,類裝載系統是通過ClassLoader來完成的。虛擬機規范中,定義了啟動類裝載器和用于定義類裝載器。在sun提供的虛擬機中,包括了啟動類裝載器、擴展類裝載器、系統類裝載器、用戶定義類裝載器。他們以父子鏈的方式組織在一起。除了啟動類裝載器,其他的裝載器都是ClassLoader的子類。ClassLoader定義了一些方法可以幫助用戶定義自己的類裝載器,如defineClass等。詳情參考Java中的ClassLoader

           

          如何卸載類數據?(第七章)

           

          3.       運行時數據區

          運行時數據區保存了所有在運行時的信息。包括方法區、Java棧、堆、程序寄存器、本地方法棧等。其中方法區和堆只在虛擬機中保存一份實例,因而需要處理多線程的同步問題;Java棧、程序寄存器是每個線程中有單獨的實例,因而對不同的線程,他們的數據是私有的。

           

          3.1   方法區

          方法區中保存了讀取的字節碼信息(包括常量池,靜態方法和靜態成員信息)、字節碼代表的Class類實例、一個指向加載它的ClassLoader實例。

          Java程序可以有兩種方式來獲取某個類的Class實例:

          1.       Class.forName()方法

          2.       Object.getClass()方法

          通過Class實例獲取和該類或接口相關的任何信息。參考Class類的定義。

          (注:對有啟動ClassLoader加載的類,Class方法中的getClassLoader方法返回null

           

          為加快執行速度,可以在方法區中引入方法表機制,記錄能被外界調用的該類的實例方法,包括父類中繼承下來的方法。(第八章詳細介紹?)

           

          方法區中根據類名搜索類信息,算法:散列、搜索樹等。

           

          3.2   Java

          虛擬機為每個線程生成一個Java棧,因而對不同的線程,棧內的數據都是私有的。Java棧由棧幀組成,Java棧的操作只有兩種,壓入棧幀和彈出棧幀。線程中每個方法的調用都會在Java棧壓入一個棧幀;每次方法返回(正常方法或拋異常返回),該方法對應的棧幀都會從棧中彈出。

           

          3.2.1          棧幀

          棧幀由操作數棧、局部變量區和棧幀數據組成。由于Java中的指令是基于棧而設計的,因而很多指令的默認操作數就是操作數棧中的數據。操作數棧用于保存指令的操作數和指令操作后的結果。

          局部變量區用于保存當前方法的局部變量。

          棧幀數據區則保存當前棧幀的信息,如指向當前類常量池的指針,用于操作數為常量池索引的指令;還有一些和特定虛擬機實現相關的信息和調試信息。

           

          3.3   程序寄存器

          每個線程在執行時都會保存當前指令的下一條指令的地址,以控制程序的之行流程。

           

          3.4  

          堆保存了程序在運行時的所有對象。在Java中,所有的對象都是保存在堆中的,而外部通過對象的引用來訪問對象。由于Java存在垃圾回收器,因而Java對象可能被移動,以減少內存碎片。其中一種實現可以很好的解決移動對象而需要改變所有該對象的引用變量的技術,即將堆分為句柄池和對象池。對象池中的對象保存了對象的真正內容,而句柄池中的項包含兩個指針,一個指向對象,一個指向類數據。一個對象引用就是指向句柄的之戰。這樣當需要移動對象時,只要改變句柄池中指向對象的指針值即可。然而這種設計是以犧牲速度為代價的,因為這樣每次訪問對象就要多經歷一次指針定位。

           

          在某些垃圾回收器實現中,對象需要額外的信息,如果引用計數的垃圾收集器,需要為每個對象記錄引用計數信息;而對另外有些機制,則可能需要暫時保存某些數據。這些額外的數據可以保存在類中,也可以在記錄在其他地方。類似的還有同步機制中的數據和記錄是否已經調用過finalize方法的信息。

           

          Java中有指令用于在內存中分配對象,卻沒有顯式的指令來釋放內存中的對象。

           

          3.5   本地方法棧

          Java方法調用本地方法的時候,當前線程的程序寄存器是不確定的值。程序的執行也轉向本地方法。本地方法可以正常返回,也可以拋出異常。拋出的異常會在調用該本地方法的指令中重新拋出。

           

          4.       執行引擎

          每個用戶線程(即不包括垃圾回收線程等)都有一個執行引擎實例,用以執行字節碼指令。

           

          5.       本地方法接口

          Java程序可以通過本地方法接口來調用本地方法。

                                                                                                                          于2010-10-06

          posted on 2011-09-05 23:20 DLevin 閱讀(2084) 評論(0)  編輯  收藏 所屬分類: 深入JVM
          主站蜘蛛池模板: 乐至县| 凤台县| 百色市| 稷山县| 陈巴尔虎旗| 沂源县| 策勒县| 上林县| 高台县| 新巴尔虎右旗| 万全县| 南靖县| 晴隆县| 太仓市| 衡水市| 曲阜市| 碌曲县| 泸西县| 横山县| 贺州市| 惠东县| 崇阳县| 金湖县| 藁城市| 清水县| 河源市| 霍林郭勒市| 崇阳县| 探索| 湘潭市| 奎屯市| 汉川市| 柳林县| 高州市| 中西区| 福清市| 昌邑市| 灌南县| 全椒县| 台山市| 沅江市|