java運行機制詳細

來源:互聯網
上載者:User

標籤:指令   程式實現   字串   對象   使用   部分   java   上進   style   

JVM(Java虛擬機器)一種用於計算裝置的規範,可用不同的方式(軟體或硬體)加以實現。編譯虛擬機器的指令集與編譯微處理器的指令集非常類似。Java虛擬機器包括一套位元組碼指令集、一組寄存器、一個棧、一個記憶體回收堆和一個儲存方法域。

       Java虛擬機器(JVM)是可運行Java代碼的假想電腦。只要根據JVM規格描述將解譯器移植到特定的電腦上,就能保證經過編譯的任何Java代碼能夠在該系統上運行。

1.為什麼要使用Java虛擬機器

       Java語言的一個非常重要的特點就是與平台的無關性。而使用Java虛擬機器是實現這一特點的關鍵。一般的進階語言如果要在不同的平台上運行,至少需要編 譯成不同的目標代碼。而引入Java語言虛擬機器後,Java語言在不同平台上運行時不需要重新編譯。Java語言使用模式Java虛擬機器屏蔽了與具體平台 相關的資訊,使得Java語言編譯器只需產生在Java虛擬機器上啟動並執行目標代碼(位元組碼),就可以在多種平台上不加修改地運行。Java虛擬機器在執行字 節碼時,把位元組碼解釋成具體平台上的機器指令執行。

Java運行機制

Java程式的運行必須經過編寫 編譯 運行 三個步驟。

編寫是指在Java開發環境中進行程式碼的輸入,最終形成尾碼名為.java的Java源檔案。

編譯是指使用Java編譯器對源檔案進行錯誤排查的過程,編譯後將產生尾碼名為.class的位元組碼檔案,這不像C語言那樣最終產生可執行檔。

運行是指使用Java解譯器將位元組碼檔案翻譯成機器代碼,執行並顯示結果。這一過程1.1所示。

 

 

位元組碼檔案是一種和任何具體機器環境及作業系統環境無關的中間代碼,它是一種二進位檔案,是Java源檔案由Java編譯器編譯後產生的目標代碼檔案。編程人員和電腦都無法直接讀懂位元組碼檔案,它必須由專用的Java解譯器來解釋執行,因此Java是一種在編譯基礎上進行解釋啟動並執行語言。

Java解譯器負責將位元組碼檔案翻譯成具體硬體環境和作業系統平台下的機器代碼,以便執行。因此Java程式不能直接運行在現有的作業系統平台上,它必須運行在被稱為Java虛擬機器的軟體平台之上。

Java虛擬機器(JVM)是運行Java程式的軟體環境,Java解譯器就是Java虛擬機器的一部分。在運行Java程式時,首先會啟動JVM,然 後由它來負責解釋執行Java的位元組碼,並且Java位元組碼只能運行於JVM之上。這樣利用JVM就可以把Java位元組碼程式和具體的硬體平台以及操作系 統環境分隔開來,只要在不同的電腦上安裝了針對於特定具體平台的JVM,Java程式就可以運行,而不用考慮當前具體的硬體平台及作業系統環境,也不用 考慮位元組碼檔案是在何種平台上產生的。JVM把這種不同軟硬體平台的具體差別隱藏起來,從而實現了真正的二進位代碼級的跨平台移植。JVM是Java平台 無關的基礎,Java的跨平台特性正是通過在JVM中運行Java程式實現的。Java的這種運行機制可以通過圖1.2說明。

 

Java語言這種“一次編寫,到處運行(write once,run anywhere)”的方式,有效地解決了目前大多數進階程式設計語言需要針對不同系統來編譯產生不同機器代碼的問題,即硬體環境和操作平台的異構問題,大大降低了程式開發、維護和管理的開銷。

需要注意的是,Java程式通過JVM可以達到跨平台特性,但JVM是不跨平台的。也就是說,不同作業系統之上的JVM是不同的,Windows平台之上的JVM不能用在Linux上面,反之亦然。

 

樣本:
我們可以通過helloworld來理解這幾個縮寫詞的具體含義:

public class HelloWorld { public static void main(String[] args) {    System.out.println("helloworld"); }}

編譯之後, 我們得到了HelloWorld.class(圖中的"Your program‘s class files")
在HelloWorld裡面, 我們調用了 Java API中的 java.lang.System這個類的靜態成員對象 out, out 的靜態方法: public static void println(String string);

然後我們讓虛擬機器來執行這個HelloWorld。
1. 虛擬機器會在classpath中找到HelloWorld.class。
2. 虛擬機器中的解譯器(interpret)會把HelloWorld.class解釋成位元組碼。
3. 把解釋後的位元組碼交由execution engin執行。
4. execution engin會調用native method(即平台相關的位元組碼)來在host system的stdout(顯示器)的指定部分列印出指定的字串。
5. 這樣, 我們就看到"helloworld"字樣了。

有了這個流程後, 我們就好理解上面幾個術語了:
a. JDK: java develop kit (JAVA API包)
b. SDK: software develop kit, 以前JDK 叫做java software develop kit, 後來出了1.2版本後, 就改名叫jdk了, 省時省力, 節約成本。
c. JRE. java runtime environment 我們的helloworld必須在JRE(JAVA運行環境,JAVA運行環境又叫JAVA平台)裡面, 才能跑起來。 所以, 顯然地, JRE其實就是JDK + JVM

d. JVM java virtual machine. 簡單地講, 就是把class檔案變成位元組碼, 然後送到excution engin中執行。而為什麼叫虛擬機器, 而不叫真實機呢? 因為JVM本身是又不能運算, 又不能讓顯示器顯示"helloworld"的, 它只能再調用host system的API, 比如在w32裡面就會調c++的API, 來讓CPU幫他做做算術運算,來調用c++裡面的API來控制顯示器顯示顯示字串。 而這些API不是JDK裡面有的,我們平時又看不見的,所以我們就叫它native api了(亦曰私房XX)。

e. 解釋平台無關。 有人會說, 在linux的裡面調用native api與w32裡面調用的api肯定不一樣吧? 那為什麼說JAVA是平台無關的呢?
其實是這樣的, 君不見java.sun.com裡面又有jdk-for-w32又有jdk-for-linux下載嗎? 剛才不是說了嗎? native api, native api, 就是我們平時看不見的api嗎! 調用native這些煩瑣的活兒都讓jdk去做了。所以我們調用的時候只用知道jdk(java api) 裡面的java.io.*能提供磁碟訪問功能, java.awt.* 能畫個框框畫個圓圓就行了嗎。 至於JDK又是怎麼調用的, 在LINXU上更圓呢? 還是在W32上更圓,(x) 這個就是JDK個人的事情了。(理論上講是一樣圓的, 當然這又和顯示器是否純平相關了:D)

同時, 這裡就引申出了另一個話題。既如何編寫平台無關的JAVA程式。 其中關鍵的一條, 就是調用且只調用jdk中的API, 而不要私自調用native api。 原因很簡單啊, JDK-for-linux和JDK-for-w32表面都是一樣的,所以我在w32裡面調用JDK寫的java程式,在linux裡面也會一樣的寫法 啊, 所以就可以移植來移植去都沒問題。(b) 但是如果我在w32裡面調用了 一個圖形顯示的native api, 當我移植到linux去的時候, 誰又能保證裡面也有相同名稱,相同參數,相同傳回值, 相同功能的native api供我調用呢!(?)

java運行機制詳細

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.