熱點推薦:
您现在的位置: 電腦知識網 >> 編程 >> Java編程 >> Java核心技術 >> 正文

JAVA文件編譯執行與虛擬機(JVM)介紹

2013-11-23 19:04:20  來源: Java核心技術 

  Java虛擬機(JVM)是可運行Java代碼的假想計算機只要根據JVM規格描述將解釋器移植到特定的計算機上就能保證經過編譯的任何Java代碼能夠在該系統上運行本文首先簡要介紹從Java文件的編譯到最終執行的過程隨後對JVM規格描述作一說明
  
  Java源文件的編譯下載解釋和執行
  Java應用程序的開發周期包括編譯下載解釋和執行幾個部分Java編譯程序將Java源程序翻譯為JVM可執行代碼?字節碼這一編譯過程同C/C++的編譯有些不同當C編譯器編譯生成一個對象的代碼時該代碼是為在某一特定硬件平台運行而產生的因此在編譯過程中編譯程序通過查表將所有對符號的引用轉換為特定的內存偏移量以保證程序運行Java編譯器卻不將對變量和方法的引用編譯為數值引用也不確定程序執行過程中的內存布局而是將這些符號引用信息保留在字節碼中由解釋器在運行過程中創立內存布局然後再通過查表來確定一個方法所在的地址這樣就有效的保證了Java的可移植性和安全性
  
  運行JVM字節碼的工作是由解釋器來完成的解釋執行過程分三部進行代碼的裝入代碼的校驗和代碼的執行裝入代碼的工作由類裝載器(class loader)完成類裝載器負責裝入運行一個程序需要的所有代碼這也包括程序代碼中的類所繼承的類和被其調用的類當類裝載器裝入一個類時該類被放在自己的名字空間中除了通過符號引用自己名字空間以外的類類之間沒有其他辦法可以影響其他類在本台計算機上的所有類都在同一地址空間內而所有從外部引進的類都有一個自己獨立的名字空間這使得本地類通過共享相同的名字空間獲得較高的運行效率同時又保證它們與從外部引進的類不會相互影響當裝入了運行程序需要的所有類後解釋器便可確定整個可執行程序的內存布局解釋器為符號引用同特定的地址空間建立對應關系及查詢表通過在這一階段確定代碼的內存布局Java很好地解決了由超類改變而使子類崩潰的問題同時也防止了代碼對地址的非法訪問
  
  隨後被裝入的代碼由字節碼校驗器進行檢查校驗器可發現操作數棧溢出非法數據類型轉化等多種錯誤通過校驗後代碼便開始執行了
  
  Java字節碼的執行有兩種方式
  即時編譯方式解釋器先將字節碼編譯成機器碼然後再執行該機器碼
  解釋執行方式解釋器通過每次解釋並執行一小段代碼來完成Java字節碼程 序的所有操作
  通常采用的是第二種方法由於JVM規格描述具有足夠的靈活性這使得將字節碼翻譯為機器代碼的工作
  
  具有較高的效率對於那些對運行速度要求較高的應用程序解釋器可將Java字節碼即時編譯為機器碼從而很好地保證了Java代碼的可移植性和高性能
  
  JVM規格描述
  JVM的設計目標是提供一個基於抽象規格描述的計算機模型為解釋程序開發人員提很好的靈活性同時也確保Java代碼可在符合該規范的任何系統上運行JVM對其實現的某些方面給出了具體的定義特別是對Java可執行代碼即字節碼(Bytecode)的格式給出了明確的規格這一規格包括操作碼和操作數的語法和數值標識符的數值表示方式以及Java類文件中的Java對象常量緩沖池在JVM的存儲映象這些定義為JVM解釋器開發人員提供了所需的信息和開發環境Java的設計者希望給開發人員以隨心所欲使用Java的自由
  
  JVM定義了控制Java代碼解釋執行和具體實現的五種規格它們是
  JVM指令系統
  JVM寄存器
  JVM棧結構
  JVM碎片回收堆
  JVM存儲區
  
  JVM指令系統
  
  JVM指令系統同其他計算機的指令系統極其相似Java指令也是由 操作碼和操作數兩部分組成操作碼為位二進制數操作數進緊隨在操作碼的後面其長度根據需要而不同操作碼用於指定一條指令操作的性質(在這裡我們采用匯編符號的形式進行說明)如iload表示從存儲器中裝入一個整數anewarray表示為一個新數組分配空間iand表示兩個整數的ret用於流程控制表示從對某一方法的調用中返回當長度大於位時操作數被分為兩個以上字節存放JVM采用了big endian的編碼方式來處理這種情況即高位bits存放在低字節中這同 Motorola及其他的RISC CPU采用的編碼方式是一致的而與Intel采用的little endian 的編碼方式即低位bits存放在低位字節的方法不同
  
  Java指令系統是以Java語言的實現為目的設計的其中包含了用於調用方法和監視多先程系統的指令Java的位操作碼的長度使得JVM最多有種指令目前已使用了多種操作碼
  
  JVM指令系統
  
  所有的CPU均包含用於保存系統狀態和處理器所需信息的寄存器組如果虛擬機定義較多的寄存器便可以從中得到更多的信息而不必對棧或內存進行訪問這有利於提高運行速度然而如果虛擬機中的寄存器比實際CPU的寄存器多在實現虛擬機時就會占用處理器大量的時間來用常規存儲器模擬寄存器這反而會降低虛擬機的效率針對這種情況JVM只設置了個最為常用的寄存器它們是
  pc程序計數器
  optop操作數棧頂指針
  frame當前執行環境指針
  vars指向當前執行環境中第一個局部變量的指針
  所有寄存器均為pc用於記錄程序的執行optopframe和vars用於記錄指向Java棧區的指針
  
  JVM棧結構
  
  作為基於棧結構的計算機Java棧是JVM存儲信息的主要方法當JVM得到一個Java字節碼應用程序後便為該代碼中一個類的每一個方法創建一個棧框架以保存該方法的狀態信息每個棧框架包括以下三類信息
  局部變量
  執行環境
  操作數棧
  
  局部變量用於存儲一個類的方法中所用到的局部變量vars寄存器指向該變量表中的第一個局部變量
  執行環境用於保存解釋器對Java字節碼進行解釋過程中所需的信息它們是上次調用的方法局部變量指針和操作數棧的棧頂和棧底指針執行環境是一個執行一個方法的控制中心例如如果解釋器要執行iadd(整數加法)首先要從frame寄存器中找到當前執行環境而後便從執行環境中找到操作數棧從棧頂彈出兩個整數進行加法運算最後將結果壓入棧頂
  操作數棧用於存儲運算所需操作數及運算的結果
  
  JVM碎片回收堆
  
  Java類的實例所需的存儲空間是在堆上分配的解釋器具體承擔為類實例分配空間的工作解釋器在為一個實例分配完存儲空間後便開始記錄對該實例所占用的內存區域的使用一旦對象使用完畢便將其回收到堆中
  在Java語言中除了new語句外沒有其他方法為一對象申請和釋放內存對內存進行釋放和回收的工作是由Java運行系統承擔的這允許Java運行系統的設計者自己決定碎片回收的方法在SUN公司開發的Java解釋器和Hot Java環境中碎片回收用後台線程的方式來執行這不但為運行系統提供了良好的性能而且使程序設計人員擺脫了自己控制內存使用的風險
  
  JVM存儲區
  
  JVM有兩類存儲區常量緩沖池和方法區常量緩沖池用於存儲類名稱方法和字段名稱以及串常量方法區則用於存儲Java方法的字節碼對於這兩種存儲區域具體實現方式在JVM規格中沒有明確規定這使得Java應用程序的存儲布局必須在運行過程中確定依賴於具體平台的實現方式
  
  JVM是為Java字節碼定義的一種獨立於具體平台的規格描述是Java平台獨立性的基礎目前的JVM還存在一些限制和不足有待於進一步的完善但無論如何JVM的思想是成功的
  
  對比分析如果把Java原程序想象成我們的C++原程序Java原程序編譯後生成的字節碼就相當於C++原程序編譯後的x的機器碼(二進制程序文件)JVM虛擬機相當於x計算機系統Java解釋器相當於xCPUxCPU上運行的是機器碼在Java解釋器上運行的是Java字節碼
  
  Java解釋器相當於運行Java字節碼的CPU但該CPU不是通過硬件實現的而是用軟件實現的Java解釋器實際上就是特定的平台下的一個應用程序只要實現了特定平台下的解釋器程序Java字節碼就能通過解釋器程序在該平台下運行這是Java跨平台的根本當前並不是在所有的平台下都有相應Java解釋器程序這也是Java並不能在所有的平台下都能運行的原因它只能在已實現了Java解釋器程序的平台下運行
From:http://tw.wingwit.com/Article/program/Java/hx/201311/26222.html
    推薦文章
    Copyright © 2005-2013 電腦知識網 Computer Knowledge   All rights reserved.