- 相關(guān)推薦
Java虛擬機是什么
什么是Java虛擬機
作為一個(gè)Java程序員,我們每天都在寫(xiě)Java代碼,我們寫(xiě)的代碼都是在一個(gè)叫做Java虛擬機的東西上執行的。但是如果要問(wèn)什么是虛擬機,恐怕很多人就會(huì )模棱兩可了。在本文中,我會(huì )寫(xiě)下我對虛擬機的理解。因為能力所限,可能有些地方描述的不夠欠當。如果你有不同的理解,歡迎交流。
我們都知道Java程序必須在虛擬機上運行。那么虛擬機到底是什么呢?先看網(wǎng)上搜索到的比較靠譜的解釋?zhuān)?/p>
虛擬機是一種抽象化的計算機,通過(guò)在實(shí)際的計算機上仿真模擬各種計算機功能來(lái)實(shí)現的。Java虛擬機有自己完善的硬體架構,如處理器、堆棧、寄存器等,還具有相應的指令系統。JVM屏蔽了與具體操作系統平臺相關(guān)的信息,使得Java程序只需生成在Java虛擬機上運行的目標代碼(字節碼),就可以在多種平臺上不加修改地運行。
這種解釋?xiě)撍闶钦_的,但是只描述了虛擬機的外部行為和功能,并沒(méi)有針對內部原理做出說(shuō)明。一般情況下我們不需要知道虛擬機的運行原理,只要專(zhuān)注寫(xiě)java代碼就可以了,這也正是虛擬機之所以存在的原因--屏蔽底層操作系統平臺的不同并且減少基于原生語(yǔ)言開(kāi)發(fā)的復雜性,使java這門(mén)語(yǔ)言能夠跨各種平臺(只要虛擬機廠(chǎng)商在特定平臺上實(shí)現了虛擬機),并且簡(jiǎn)單易用。這些都是虛擬機的外部特性,但是從這些信息來(lái)解釋虛擬機,未免太籠統了,無(wú)法讓我們知道內部原理。
從進(jìn)程的角度解釋JVM
讓我們嘗試從操作系統的層面來(lái)理解虛擬機。我們知道,虛擬機是運行在操作系統之中的,那么什么東西才能在操作系統中運行呢?當然是進(jìn)程,因為進(jìn)程是操作系統中的執行單位?梢赃@樣理解,當它在運行的時(shí)候,它就是一個(gè)操作系統中的進(jìn)程實(shí)例,當它沒(méi)有在運行時(shí)(作為可執行文件存放于文件系統中),可以把它叫做程序。
對命令行比較熟悉的同學(xué),都知道其實(shí)一個(gè)命令對應一個(gè)可執行的二進(jìn)制文件,當敲下這個(gè)命令并且回車(chē)后,就會(huì )創(chuàng )建一個(gè)進(jìn)程,加載對應的可執行文件到進(jìn)程的地址空間中,并且執行其中的指令。下面對比C語(yǔ)言和Java語(yǔ)言的HelloWorld程序來(lái)說(shuō)明問(wèn)題。
首先編寫(xiě)C語(yǔ)言版的HelloWorld程序。
[cpp] view plain copy#include
#include
int main(void) {
printf("hello world
");
return 0;
}
編譯C語(yǔ)言版的HelloWorld程序:
[plain] view plain copygcc HelloWorld.c -o HelloWorld
運行c語(yǔ)言版的HelloWorld程序:
[plain] view plain copyzhangjg@linux:/deve/workspace/HelloWorld/src$ ./HelloWorld
hello world
gcc編譯器編譯后的文件直接就是可操作系統識別的二進(jìn)制可執行文件,當我們在命令行中敲下 ./HelloWorld這條命令的時(shí)候, 直接創(chuàng )建一個(gè)進(jìn)程, 并且將可執行文件加載到進(jìn)程的地址空間中, 執行文件中的指令。
作為對比, 我們看一下Java版HelloWord程序的編譯和執行形式。
首先編寫(xiě)源文件HelloWord.java :
[java] view plain copypublic class HelloWorld {
public static void main(String[] args) {
System.out.println("HelloWorld");
}
}
編譯Java版的HelloWorld程序:
[java] view plain copyzhangjg@linux:/deve/workspace/HelloJava/src$ javac HelloWorld.java
zhangjg@linux:/deve/workspace/HelloJava/src$ ls
HelloWorld.class HelloWorld.java
運行Java版的HelloWorld程序:
[plain] view plain copyzhangjg@linux:/deve/workspace/HelloJava/src$ java -classpath . HelloWorld
HelloWorld
從上面的過(guò)程可以看到, 我們在運行Java版的HelloWorld程序的時(shí)候, 敲入的命令并不是 ./HelloWorld.class 。 因為class文件并不是可以直接操作系統識別的二進(jìn)制可執行文件 。 我們敲入的是java這個(gè)命令。 這個(gè)命令說(shuō)明, 我們首先啟動(dòng)的是一個(gè)叫做java的程序, 這個(gè)java程序在運行起來(lái)之后就是一個(gè)JVM進(jìn)程實(shí)例。
上面的命令執行流程是這樣的:
java命令首先啟動(dòng)虛擬機進(jìn)程,虛擬機進(jìn)程成功啟動(dòng)后,讀取參數“HelloWorld”,把他作為初始類(lèi)加載到內存,對這個(gè)類(lèi)進(jìn)行初始化和動(dòng)態(tài)鏈接(關(guān)于類(lèi)的初始化和動(dòng)態(tài)鏈接會(huì )在后面的博客中介紹),然后從這個(gè)類(lèi)的main方法開(kāi)始執行。也就是說(shuō)我們的class文件不是直接被系統加載后直接在cpu上執行的,而是被一個(gè)叫做虛擬機的進(jìn)程托管的。首先必須虛擬機進(jìn)程啟動(dòng)就緒,然后由虛擬機中的類(lèi)加載器加載必要的class文件,包括jdk中的基礎類(lèi)(如String和Object等),然后由虛擬機進(jìn)程解釋class字節碼指令,把這些字節碼指令翻譯成本機cpu能夠識別的指令,才能在cpu上運行。
從這個(gè)層面上來(lái)看,在執行一個(gè)所謂的java程序的時(shí)候,真真正正在執行的是一個(gè)叫做Java虛擬機的進(jìn)程,而不是我們寫(xiě)的一個(gè)個(gè)的class文件。這個(gè)叫做虛擬機的進(jìn)程處理一些底層的操作,比如內存的分配和釋放等等。我們編寫(xiě)的class文件只是虛擬機進(jìn)程執行時(shí)需要的“原料”。這些“原料”在運行時(shí)被加載到虛擬機中,被虛擬機解釋執行,以控制虛擬機實(shí)現我們java代碼中所定義的一些相對高層的操作,比如創(chuàng )建一個(gè)文件等,可以將class文件中的信息看做對虛擬機的控制信息,也就是一種虛擬指令。
編程語(yǔ)言也有自己的原理, 學(xué)習一門(mén)語(yǔ)言, 主要是把它的原理搞明白。 看似一個(gè)簡(jiǎn)單的HelloWorld程序, 也有很多深入的內容值得剖析。
【Java虛擬機是什么】相關(guān)文章:
Java架構師的職責02-27
Java架構師的具體職責09-23
【優(yōu)選】Java架構師的職責02-27
Java高級開(kāi)發(fā)工程師的基本職責03-15
生命是什么09-08
幸福是什么08-21