<rt id="bn8ez"></rt>
<label id="bn8ez"></label>

  • <span id="bn8ez"></span>

    <label id="bn8ez"><meter id="bn8ez"></meter></label>

    qileilove

    blog已經轉移至github,大家請訪問 http://qaseven.github.io/

    深入Java虛擬機之虛擬機體系結構

     工作以來,代碼越寫越多,程序也越來越臃腫,效率越來越低,對于我這樣一個追求完美的程序員來說,這是絕對不被允許的,于是除了不斷優化程序結構外,內存優化和性能調優就成了我慣用的“伎倆”。

      要對Java程序進行內存優化和性能調優,不了解虛擬機的內部原理(或者叫規范更嚴謹一點)是肯定不行的,這里推薦一本好書《深入Java虛擬機(第二版)》(Bill Venners著,曹曉剛 蔣靖 譯,實際上本文正是作者閱讀本書之后,對Java虛擬機的個人理解闡述)。當然了,了解Java虛擬機的好處并不僅限于上述兩點好處。從更深一點的技術層面上看,了解Java虛擬機的規范和實現,將更加有助于我們編寫高效、穩定的Java代碼。比如,假如了解Java虛擬機的內存模型,了解虛擬機的內存回收機制,那么我們就不會過分依賴它,而會在需要的時候顯式的"釋放內存"(Java代碼不能顯式釋放內存,但是可以通過釋放對象引用告知垃圾回收器回收該對象需要被回收),以降低不必要的內存消耗;假如我們了解Java棧的工作原理,那么我們就可以通過減少遞歸層數,減少循環次數來降低堆棧溢出的風險。可能對于應用開發人員來說,可能不會直接去涉及這些Java虛擬機底層實現的工作,但是了解這些背景知識,或多或少,都會對我們寫的程序產生潛移默化的好的影響。

      本篇文章,將簡明扼要的說明Java虛擬機的體系結構和內存模型,如有用詞不妥或解釋不準確之處,請不吝指正,深感榮幸!

      Java 虛擬機體系結構

      類裝載子系統

      Java虛擬機有兩種類裝載器,分別是啟動類裝載器和用戶自定義裝載器。

      通類裝載子系統通過類的全限定名(包名和類名,網絡裝載還包括 URL)將 Class 裝載進運行時數據區。對于每一個被裝載的類型,Java虛擬機都會創建一個java.lang.Class類的實例來代表該類型,該實例被放在內存中的堆區,而裝載的類型信息則位于方法區,這一點和所有其他對象都是一樣的。

      類裝載子系統在裝載一個類型前,除了要定位和導入對應的二進制class文件外,還要驗證導入類的正確性,為類變量分配并初始化內存,以及解析符號引用為直接引用,這些動作嚴格按照以下順序進行:

      1)裝載——查找并裝載類型的二進制數據;

      2)連接——執行驗證,準備以及解析(可選)

      3)驗證 確保被導入類型的正確性

      4)準備 為類變量分配內存,并將其初始化為默認值

      5)解析 把類型中的符號引用轉換為直接應用

      方法區

      對于每一個被類裝載子系統裝載的類型,虛擬機都會保存下列數據到方法區:

      ◆  類型的全限定名

      ◆ 類型超類的全限定名(java.lang.Object沒有超類)

      ◆ 類型是類類型還是接口類型

      ◆ 類型的訪問修飾符

      ◆ 任何直接超接口的全限定名有序列表

     除了上述基本類型信息,還將保存如下信息:

      ◆ 類型的常量池

      ◆ 字段信息(包括字段名、字段類型、字段修飾符)

      ◆ 方法信息(包括方法名、返回類型、參數的數量和類型、方法修飾符,如果方法不是抽象和本地的,還將保存方法的字節碼、操作數棧和該方法棧幀中的局部變量區的大小和異常表)

      ◆ 常量以外的所有類變量(其實就是類的靜態變量,因為靜態變量是所有實例共享的,且與類型直接相關,所以他們是類一級的變量,作為類的成員被保存在方法區)

      一個到類ClassLoader的引用

  • //返回的就是剛才保存的ClassLoader引用   
  • String.class.getClassLoader();
  •   一個到Class類的引用

  • //將返回剛才保存的Class類的引用   
  • String.class;
  •   注意,方法區也是可以被垃圾回收器回收的。

      堆

      Java程序在運行時創建的所有類實例或數組都放在同一個堆中,而每一個Java虛擬機也是有一個對空間,所有線程共享一個堆(這就是一個多線程的Java程序會產生對象訪問的同步問題的原因了)。

      由于每一種Java虛擬機都有對虛擬機規范的不同實現,所以我們可能不知道每一種Java虛擬機在堆中是以何種形式表示對象實例的,不過我們可以通過下面這可能的實現來一窺端倪:


      程序計數器

      對于運行中的Java程序而言,每一個線程都有自己的PC(程序計數器)寄存器,它是在該線程啟動時創建的,大小為一個字長,用來保存需要被執行的下一行代碼的位置。

      Java棧

      每一個線程都有一個Java棧,以棧幀為單位保存線程的運行狀態。虛擬機對Java棧的操作有兩種:壓棧和出棧,二者都已幀為單位。棧幀保存了傳入參數、局部變量、中間運算結果等數據,在方法完成時被彈出,然后釋放。

      看一下兩個局部變量相加時棧幀的內存快照

      本地方法棧

      這是 Java 調用操作系統本地庫的地方,用來實現 JNI(Java Native Interface,Java 本地接口)

      執行引擎

      Java虛擬機的核心,控制裝入 Java 字節碼并解析;對于運行中的Java程序而言,每一個線程都是一個獨立的虛擬機執行引擎的實例,從線程生命周期的開始到結束,他要么在執行字節碼,要么在執行本地方法。

      本地接口

      連接了本地方法棧和操作系統庫。

      注:文中所有提到“Java虛擬機”的地方都是指“JavaEE和JavaSE平臺的Java虛擬機規范”。

    posted on 2011-12-31 00:15 順其自然EVO 閱讀(172) 評論(0)  編輯  收藏


    只有注冊用戶登錄后才能發表評論。


    網站導航:
     
    <2011年12月>
    27282930123
    45678910
    11121314151617
    18192021222324
    25262728293031
    1234567

    導航

    統計

    常用鏈接

    留言簿(55)

    隨筆分類

    隨筆檔案

    文章分類

    文章檔案

    搜索

    最新評論

    閱讀排行榜

    評論排行榜

    主站蜘蛛池模板: 亚洲精品视频在线免费| 在线观看午夜亚洲一区| 亚洲av专区无码观看精品天堂| 无码av免费一区二区三区试看| 亚洲三级电影网址| 88xx成人永久免费观看| 亚洲欧洲国产经精品香蕉网| 亚洲一级毛片免费看| 亚洲第一福利视频| 成人无码WWW免费视频| 亚洲精品无码午夜福利中文字幕| 曰批免费视频播放在线看片二 | 亚洲黄色免费网站| 亚洲狠狠ady亚洲精品大秀| 国产成人免费午夜在线观看| 亚洲男人天堂2022| 国产成人一区二区三区免费视频| 老司机免费午夜精品视频| 亚洲无人区午夜福利码高清完整版| 182tv免费视频在线观看| 亚洲熟妇av一区二区三区下载| 最近最好的中文字幕2019免费| 亚洲爆乳AAA无码专区| 国产成人高清亚洲| 最近中文字幕2019高清免费| 亚洲日本VA午夜在线电影| 亚洲一级特黄大片无码毛片| 免费观看91视频| 亚洲色中文字幕在线播放| 亚洲国产精品人人做人人爱| 免费一级毛片在线播放视频| 亚洲日韩国产精品乱-久| 亚洲av手机在线观看| 久久国产精品萌白酱免费| 亚洲天堂2017无码中文| 四虎免费影院4hu永久免费| 精品国产麻豆免费人成网站| 日韩亚洲国产综合高清| 亚洲精品无码av天堂| 精品熟女少妇a∨免费久久| AV激情亚洲男人的天堂国语|