本人博客原文:http://www.deleiguo.com/archives/172
轉(zhuǎn)發(fā)請附帶原文地址
簡介
基本上一開始學(xué)習(xí)Java,就接觸到第一個(gè)Java的命令:java -version
這個(gè)命令最常用的就是用來查看當(dāng)前服務(wù)器的JDK環(huán)境版本带欢,以此驗(yàn)證服務(wù)器環(huán)境變量是否已正確的設(shè)置好JDK隔盛。
最常見的結(jié)果一般有兩種:
- Sun JDK:
delei@DeleitekiMBP:~$ java -version
java version "1.7.0_79"
Java(TM) SE Runtime Environment (build 1.7.0_79-b15)
Java HotSpot(TM) 64-Bit Server VM (build 24.79-b02, mixed mode)
- Open JDK:
root@ubuntu-server:~# java -version
java version "1.7.0_95"
OpenJDK Runtime Environment (IcedTea 2.6.4) (7u95-2.6.4-0ubuntu0.15.10.1)
OpenJDK 64-Bit Server VM (build 24.95-b01, mixed mode)
第一行:JDK的版本號
第二行:JDK的運(yùn)行環(huán)境
但第三行是指的什么宵距,在一開始沒留意也不理解這一行包含著哪些信息,這里以Sun JDK為例來稍微深入看一下.
Java HotSpot(TM) 64-Bit Server VM (build 24.79-b02, mixed mode)
-
Java HotSpot(TM)
-
64-Bit
- 如果安裝的是64位的則是64-bit,如果安裝是32位役耕,則為32-bit采转。
- 這里不是服務(wù)器的操作系統(tǒng),而是指的當(dāng)前安裝JDK
Server VM
Server VM
Client VM
mixed mode
mixed mode:混合模式
class data sharing:類數(shù)據(jù)共享
interpreted mode:解釋模式
JVM類型
首先要知道的的是Server VM和Client VM可以理解是不同的虛擬機(jī)瞬痘。
如果操作系統(tǒng)是64位的故慈,只能是Server VM,Client VM只有在32位上才有框全。Oracle官方
Server VM和Client VM有什么區(qū)別察绷?在官網(wǎng)的FAQ中有如下的描述:
JIT Compiler
1.What's the difference between the -client and -server systems?
These two systems are different binaries. They are essentially two different compilers (JITs)interfacing to the same runtime system. The client system is optimal for applications which need fast startup times or small footprints, the server system is optimal for applications where the overall performance is most important. In general the client system is better suited for interactive applications such as GUIs. Some of the other differences include the compilation policy,heap defaults, and inlining policy.
大致翻譯:
這兩個(gè)JVM采用不同的編譯器。
Client JVM適合快速啟動和較小內(nèi)存的津辩,它適合強(qiáng)調(diào)交互的應(yīng)用拆撼,比如GUI(桌面級應(yīng)用界面);
Server JVM則是偏重執(zhí)行時(shí)候的效率的喘沿。
其他不同的地方"編譯策略"闸度、"默認(rèn)堆大小"、"內(nèi)嵌策略"
2.Where do I get the server and client systems?
Client and server systems are both downloaded with the 32-bit Solaris and Linux downloads. For 32-bit Windows, if you download the JRE, you get only the client, you'll need to download the SDK to get both systems.
For 64-bit, only the server system is included. On Solaris, the 64-bit JRE is an overlay on top of the 32-bit distribution. However, on Linux and Windows, it's a completely separate distribution.
主要內(nèi)容翻譯:
在32位的系統(tǒng)中摹恨,如果下載JRE,則只有client筋岛;
從Java SE 5.0開始,在64位的系統(tǒng)中晒哄,默認(rèn)的時(shí)候Server,32位的默認(rèn)
以上是從官方得到的原理/規(guī)范使用上的一些說明肪获。接下來看在實(shí)際當(dāng)中寝凌,如何切換Server VM和Client VM:
- 想要在windows系統(tǒng)中進(jìn)行切換,需要下載JDK而不是JRE;
- 在Windows 系統(tǒng)中孝赫,找到JDK(%JAVA_HOME%)安裝的目錄
/jre/lib
较木,該目錄下會有server
和client
兩個(gè)不同的目錄;
命令切換(推薦)
在CMD/終端命令中,執(zhí)行java -server -version
和java -client -version
即可切換;修改文件(永久切換)
在jre/lib/i386/
(32位的JDK有i386文件夾)青柄,編輯修改jvm.cfg文件
# List of JVMs that can be used as an option to java, javac, etc.
# Order is important -- first in this list is the default JVM.
# NOTE that this both this file and its format are UNSUPPORTED and
# WILL GO AWAY in a future release.
#
# You may also select a JVM in an arbitrary location with the
# "-XXaltjvm=<jvm_dir>" option, but that too is unsupported
# and may not be available in a future release.
#
-client KNOWN
-server KNOWN
-hotspot ALIASED_TO -client
-classic WARN
-native ERROR
-green ERROR
# Order is important -- first in this list is the default JVM.
第一行的配置則為默認(rèn)的JVM伐债,這里第一行是-client,所有默認(rèn)是Client VM;
要想用Server VM致开,則將第二行與第三行調(diào)換位置保存即可;
應(yīng)用場景
- 我們時(shí)常會在開發(fā)/生產(chǎn)環(huán)境中對web 服務(wù)器調(diào)整JVM的參數(shù)峰锁,一般來說目前服務(wù)器都是64位的,可以先用java -version來查看環(huán)境;
- 根據(jù)應(yīng)用的場景需要双戳,在jvm中加上
-server
參數(shù);
JVM運(yùn)行模式
在CMD/終端命令中虹蒋,執(zhí)行java -X
root@ubuntu-server:~# java -X
-Xmixed mixed mode execution (default)
-Xint interpreted mode execution only
在此可以知道m(xù)ixed是默認(rèn)的模式;
JVM模式有:-Xint, -Xcomp, 和 -Xmixed
** -Xint**
在解釋模式(interpreted mode)下,-Xint標(biāo)記會強(qiáng)制JVM執(zhí)行所有的字節(jié)碼魄衅,當(dāng)然這會降低運(yùn)行速度峭竣,通常低10倍或更多。** -Xcomp**
-Xcomp參數(shù)與它(-Xint)正好相反晃虫,JVM在第一次使用時(shí)會把所有的字節(jié)碼編譯成本地代碼皆撩,從而帶來最大程度的優(yōu)化。這聽起來不錯(cuò)哲银,因?yàn)檫@完全繞開了緩慢的解釋器-Xmixed
混合模式(mixed mode)毅访,是JVM的默認(rèn)工作模式。它會同時(shí)使用編譯模式和解釋模式盘榨。對于字節(jié)碼中多次被調(diào)用的部分喻粹,JVM會將其編譯成本地代碼以提高執(zhí)行效率;而被調(diào)用很少(甚至只有一次)的方法在解釋模式下會繼續(xù)執(zhí)行草巡,從而減少編譯和優(yōu)化成本守呜。JIT編譯器在運(yùn)行時(shí)創(chuàng)建方法使用文件,然后一步一步的優(yōu)化每一個(gè)方法山憨,有時(shí)候會主動的優(yōu)化應(yīng)用的行為查乒。這些優(yōu)化技術(shù),比如積極的分支預(yù)測(optimistic branch prediction)郁竟,如果不先分析應(yīng)用就不能有效的使用玛迄。這樣將頻繁調(diào)用的部分提取出來,編譯成本地代碼棚亩,也就是在應(yīng)用中構(gòu)建某種熱點(diǎn)(即HotSpot蓖议,這也是HotSpot JVM名字的由來)。使用混合模式可以獲得最好的執(zhí)行效率讥蟆。
在CMD/終端命令中勒虾,可以直接通過命令來切換模式:
root@ubuntu-server:~# java -Xint -version
java version "1.7.0_95"
OpenJDK Runtime Environment (IcedTea 2.6.4) (7u95-2.6.4-0ubuntu0.15.10.1)
OpenJDK 64-Bit Server VM (build 24.95-b01, interpreted mode)
root@ubuntu-server:~# java -Xcomp -version
java version "1.7.0_95"
OpenJDK Runtime Environment (IcedTea 2.6.4) (7u95-2.6.4-0ubuntu0.15.10.1)
OpenJDK 64-Bit Server VM (build 24.95-b01, compiled mode)
** 代碼驗(yàn)證**
我們通過一個(gè)小的Java代碼來驗(yàn)證下不同mode下的執(zhí)行耗時(shí)(Server VM)
public class JVMModeTest {
private static void test() {//循環(huán)++
for (int i =0;i<1000000000;i++) {
}
}
public static void main(String[] args) {
long start = System.currentTimeMillis();
test();
long end = System.currentTimeMillis();
System.out.println(end-start);//打印執(zhí)行耗時(shí)
}
}
結(jié)果如下:
root@ubuntu-server:~/work/java$ java -Xcomp JVMModeTest
2
root@ubuntu-server:~/work/java$ java -Xint JVMModeTest
28562
root@ubuntu-server:~/work/java$ java -Xmixed JVMModeTest
18
由于即時(shí)編譯器編譯本地代碼需要占用程序運(yùn)行時(shí)間,要編譯出優(yōu)化程度更高的代碼瘸彤,所花費(fèi)的時(shí)間可能更長修然;而且想要編譯出優(yōu)化程度更高的代碼,解釋器可能還要替編譯器收集性能監(jiān)控信息质况,這對解釋執(zhí)行的速度也有影響愕宋。為了在程序啟動響應(yīng)速度與運(yùn)行效率之間達(dá)到最佳平衡,HotSpot虛擬機(jī)還會逐漸啟用分層編譯(Tiered Compilation)[4]的策略结榄,分層編譯的概念在JDK 1.6時(shí)期出現(xiàn)中贝,后來一直處于改進(jìn)階段,最終在JDK 1.7的Server模式虛擬機(jī)中作為默認(rèn)編譯策略被開啟潭陪。分層編譯根據(jù)編譯器編譯雄妥、優(yōu)化的規(guī)模與耗時(shí)最蕾,劃分出不同的編譯層次,其中包括:
第0層老厌,程序解釋執(zhí)行瘟则,解釋器不開啟性能監(jiān)控功能(Profiling),可觸發(fā)第1層編譯枝秤。
第1層醋拧,也稱為C1編譯,將字節(jié)碼編譯為本地代碼淀弹,進(jìn)行簡單丹壕、可靠的優(yōu)化,如有必要將加入性能監(jiān)控的邏輯薇溃。
第2層(或2層以上)菌赖,也稱為C2編譯,也是將字節(jié)碼編譯為本地代碼沐序,但是會啟用一些編譯耗時(shí)較長的優(yōu)化琉用,甚至?xí)鶕?jù)性能監(jiān)控信息進(jìn)行一些不可靠的激進(jìn)優(yōu)化。
實(shí)施分層編譯后策幼,Client Compiler和Server Compiler將會同時(shí)工作邑时,許多代碼都可能會被多次編譯,用Client Compiler獲取更高的編譯速度特姐,用Server Compiler來獲取更好的編譯質(zhì)量晶丘,在解釋執(zhí)行的時(shí)候也無須再承擔(dān)收集性能監(jiān)控信息的任務(wù)
注:
[1] 在虛擬機(jī)中習(xí)慣將Client Compiler稱為C1,將Server Compiler稱為C2唐含。
參考/引用
http://my.oschina.net/itblog/blog/507822
http://ifeve.com/useful-jvm-flags-part-1-jvm-types-and-compiler-modes-2/
深入理解Java虛擬機(jī):JVM高級特性與最佳實(shí)踐(第2版)
http://www.oracle.com/technetwork/java/hotspotfaq-138619.html
http://docs.oracle.com/javase/7/docs/technotes/guides/vm/server-class.html