部分商用虛擬機中,Java程序最初是通過解釋器對.class文件進行解釋執行的,當虛擬機發現某個方法或代碼塊運行地特別頻繁的時候,就會把這些代碼認定為熱點代碼Hot Spot Code(這也是我們使用的虛擬機HotSpot名稱的由來)。為了提高熱點代碼的執行效率,在運行時,虛擬機將會把這些代碼編譯成與本地平台相關的機器碼,並進行各種層次的優化,完成這個任務的編譯器叫做即時編譯器(Just In Time Compiler,即JIT編譯器)。JIT編譯器並不是虛擬機必需的部分,Java虛擬機規范並沒有要求要有JIT編譯器的存在,更沒有限定或指導JIT編譯器應該如何去實現。但是,JIT編譯器性能的好壞、代碼優化程度的高低卻是衡量一款商用虛擬機優秀與否的最關鍵指標之一。
解釋器和編譯器其實和編譯器各有優勢:
1、當程序需要迅速啟動和執行的時候,解釋器可以先發揮作用,省去編譯的時間,立即執行
2、在程序運行后,隨着時間的推移,編譯器逐漸發揮作用,把越來越多的代碼編譯成本地代碼之后,可以獲取更高的執行效率
我們使用的HotSpot中內置了兩個JIT編譯器,即C1編譯器和C2編譯器,默認采用的是解釋器和一個編輯器配合的方式進行工作。HotSpot在啟動的時候會根據自身版本以及宿主機器的硬件性能自動選擇運行模式,比如會檢測宿主機器是否為服務器、比如J2SE會檢測主機是否有至少2個CPU和至少2GB的內存。
1、如果是,則虛擬機會以Server模式運行,該模式與C2編譯器共同運行,更注重編譯的質量,啟動速度慢,但是運行效率高,適合用在服務器環境下,針對生產環境進行了優化
2、如果不是,則虛擬機會以Client模式運行,該模式與C1編譯器共同運行,更注重編譯的速度,啟動速度快,更適合用在客戶端的版本下,針對GUI進行了優化
有兩種方法查看虛擬機是運行在Client模式下還是Server模式下:
1、在程序命令行運行“java -version”命令,查看的是你本地安裝的虛擬機是信息
2、比如我們用Eclipse或者MyEclipse運行程序,一般使用的都是工具自帶的JRE,虛擬機並不是本地安裝的虛擬機。這時候怎么辦呢,可以通過在程序中運行下面的語句來查看虛擬機信息
System.out.println(System.getProperty("java.vm.name"));
我這里的運行結果是
Java HotSpot(TM) 64-Bit Server VM
當然要改變虛擬機運行的模式也可以,只需要改jvm.cfg就可以了。我們可以從以下幾個地方找到jvm.cfg:
1、32位的JDK的文件路徑是 JAVA_HOME/jre/lib/i386/jvm.cfg
2、64位的JDK的文件路徑是 JAVA_HOME/jre/lib/amd64/jvm.cfg
3、MyEclipse在 .../Common/binary/com.sun.java.jdk.win32.x86_64_1.6.0.013/jre/lib/amd64/jvm.cfg
目前64位只支持Server模式,文件內容都是一樣的,上面的注釋不去管它,剩下的就是這些:
-server KNOWN -client IGNORE -hotspot ALIASED_TO -server -classic WARN -native ERROR -green ERROR
由於我的電腦裝的是64位JDK,所以是“-client INGORE”。同時支持Server模式和Client模式的,應該是“-server KNOWN”和“-client KNOWN”,一般只需要變更這兩個配置的先后順序即可,但是前提是JAVA_HOME/jre/bin目錄下同時存在server和client兩個文件夾,分別對應着各自的虛擬機,缺少一個,切換后就會報錯。