上善若水
          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

          最新隨筆

          搜索

          •  

          積分與排名

          • 積分 - 896776
          • 排名 - 42

          最新評(píng)論

          閱讀排行榜

          評(píng)論排行榜

          Java虛擬機(jī)體內(nèi)部系結(jié)構(gòu)包括class文件、類裝載子系統(tǒng)、運(yùn)行時(shí)數(shù)據(jù)區(qū)、之行引擎、本地方法調(diào)用結(jié)構(gòu),其中運(yùn)行時(shí)數(shù)據(jù)區(qū)包括方法區(qū)、堆、Java棧、程序計(jì)數(shù)器、本地方法棧等。具體結(jié)構(gòu)如下圖所示(摘自Inside Java Virtual Machine):


           

          1.       class文件

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

          class文件中,包含了定義一個(gè)類或接口的所有信息,包括類名、訪問(wèn)權(quán)限、父類名、繼承的所有接口、所有字段、所有方法、方法中的代碼、屬性等信息,并且每個(gè)class文件的開(kāi)頭還包含了魔術(shù)值和版本信息,魔術(shù)值用以標(biāo)識(shí)當(dāng)前的字節(jié)碼是合法的字節(jié)碼,版本表示生成當(dāng)前字節(jié)碼的編譯器版本,從而虛擬機(jī)獲知其版本而做特定處理,如果對(duì)于虛擬機(jī)不支持的字節(jié)碼版本號(hào)拒絕加載。

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

           

          2.       類裝載子系統(tǒng)

          類裝載子系統(tǒng)負(fù)責(zé)查找class文件,讀取字節(jié)碼,做部分簡(jiǎn)單的檢驗(yàn),如魔數(shù)是否正確,版本是否受支持,各種數(shù)據(jù)格式是否正確等。部分解析后的字節(jié)碼數(shù)據(jù)存放到方法區(qū)中,最后創(chuàng)建字節(jié)碼代表的類或接口的Class實(shí)例。

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

           

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

           

          3.       運(yùn)行時(shí)數(shù)據(jù)區(qū)

          運(yùn)行時(shí)數(shù)據(jù)區(qū)保存了所有在運(yùn)行時(shí)的信息。包括方法區(qū)、Java棧、堆、程序寄存器、本地方法棧等。其中方法區(qū)和堆只在虛擬機(jī)中保存一份實(shí)例,因而需要處理多線程的同步問(wèn)題;Java棧、程序寄存器是每個(gè)線程中有單獨(dú)的實(shí)例,因而對(duì)不同的線程,他們的數(shù)據(jù)是私有的。

           

          3.1   方法區(qū)

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

          Java程序可以有兩種方式來(lái)獲取某個(gè)類的Class實(shí)例:

          1.       Class.forName()方法

          2.       Object.getClass()方法

          通過(guò)Class實(shí)例獲取和該類或接口相關(guān)的任何信息。參考Class類的定義。

          (注:對(duì)有啟動(dòng)ClassLoader加載的類,Class方法中的getClassLoader方法返回null

           

          為加快執(zhí)行速度,可以在方法區(qū)中引入方法表機(jī)制,記錄能被外界調(diào)用的該類的實(shí)例方法,包括父類中繼承下來(lái)的方法。(第八章詳細(xì)介紹?)

           

          方法區(qū)中根據(jù)類名搜索類信息,算法:散列、搜索樹(shù)等。

           

          3.2   Java

          虛擬機(jī)為每個(gè)線程生成一個(gè)Java棧,因而對(duì)不同的線程,棧內(nèi)的數(shù)據(jù)都是私有的。Java棧由棧幀組成,Java棧的操作只有兩種,壓入棧幀和彈出棧幀。線程中每個(gè)方法的調(diào)用都會(huì)在Java棧壓入一個(gè)棧幀;每次方法返回(正常方法或拋異常返回),該方法對(duì)應(yīng)的棧幀都會(huì)從棧中彈出。

           

          3.2.1          棧幀

          棧幀由操作數(shù)棧、局部變量區(qū)和棧幀數(shù)據(jù)組成。由于Java中的指令是基于棧而設(shè)計(jì)的,因而很多指令的默認(rèn)操作數(shù)就是操作數(shù)棧中的數(shù)據(jù)。操作數(shù)棧用于保存指令的操作數(shù)和指令操作后的結(jié)果。

          局部變量區(qū)用于保存當(dāng)前方法的局部變量。

          棧幀數(shù)據(jù)區(qū)則保存當(dāng)前棧幀的信息,如指向當(dāng)前類常量池的指針,用于操作數(shù)為常量池索引的指令;還有一些和特定虛擬機(jī)實(shí)現(xiàn)相關(guān)的信息和調(diào)試信息。

           

          3.3   程序寄存器

          每個(gè)線程在執(zhí)行時(shí)都會(huì)保存當(dāng)前指令的下一條指令的地址,以控制程序的之行流程。

           

          3.4  

          堆保存了程序在運(yùn)行時(shí)的所有對(duì)象。在Java中,所有的對(duì)象都是保存在堆中的,而外部通過(guò)對(duì)象的引用來(lái)訪問(wèn)對(duì)象。由于Java存在垃圾回收器,因而Java對(duì)象可能被移動(dòng),以減少內(nèi)存碎片。其中一種實(shí)現(xiàn)可以很好的解決移動(dòng)對(duì)象而需要改變所有該對(duì)象的引用變量的技術(shù),即將堆分為句柄池和對(duì)象池。對(duì)象池中的對(duì)象保存了對(duì)象的真正內(nèi)容,而句柄池中的項(xiàng)包含兩個(gè)指針,一個(gè)指向?qū)ο螅粋€(gè)指向類數(shù)據(jù)。一個(gè)對(duì)象引用就是指向句柄的之戰(zhàn)。這樣當(dāng)需要移動(dòng)對(duì)象時(shí),只要改變句柄池中指向?qū)ο蟮闹羔樦导纯伞H欢@種設(shè)計(jì)是以犧牲速度為代價(jià)的,因?yàn)檫@樣每次訪問(wèn)對(duì)象就要多經(jīng)歷一次指針定位。

           

          在某些垃圾回收器實(shí)現(xiàn)中,對(duì)象需要額外的信息,如果引用計(jì)數(shù)的垃圾收集器,需要為每個(gè)對(duì)象記錄引用計(jì)數(shù)信息;而對(duì)另外有些機(jī)制,則可能需要暫時(shí)保存某些數(shù)據(jù)。這些額外的數(shù)據(jù)可以保存在類中,也可以在記錄在其他地方。類似的還有同步機(jī)制中的數(shù)據(jù)和記錄是否已經(jīng)調(diào)用過(guò)finalize方法的信息。

           

          Java中有指令用于在內(nèi)存中分配對(duì)象,卻沒(méi)有顯式的指令來(lái)釋放內(nèi)存中的對(duì)象。

           

          3.5   本地方法棧

          當(dāng)Java方法調(diào)用本地方法的時(shí)候,當(dāng)前線程的程序寄存器是不確定的值。程序的執(zhí)行也轉(zhuǎn)向本地方法。本地方法可以正常返回,也可以拋出異常。拋出的異常會(huì)在調(diào)用該本地方法的指令中重新拋出。

           

          4.       執(zhí)行引擎

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

           

          5.       本地方法接口

          Java程序可以通過(guò)本地方法接口來(lái)調(diào)用本地方法。

                                                                                                                          于2010-10-06

          posted on 2011-09-05 23:20 DLevin 閱讀(2086) 評(píng)論(0)  編輯  收藏 所屬分類: 深入JVM
          主站蜘蛛池模板: 忻州市| 武义县| 增城市| 隆子县| 恩施市| 民丰县| 旌德县| 新邵县| 石屏县| 若羌县| 大石桥市| 聂拉木县| 诸城市| 宁阳县| 常州市| 淮北市| 温州市| 忻州市| 子洲县| 鄢陵县| 盐城市| 禄丰县| 菏泽市| 时尚| 揭东县| 鄂伦春自治旗| 本溪| 怀化市| 吴堡县| 平昌县| 阿城市| 垫江县| 木兰县| 峡江县| 富顺县| 岫岩| 温泉县| 台东县| 河东区| 唐山市| 元朗区|