簡介
在本文中找到有關(guān)于32位JVM和64位JVM之間的區(qū)別的一些常見問題的答案撵枢。你將學(xué)到在這兩者之間進(jìn)行遷移時要考慮的所有事情民晒,將有助于你更好地實(shí)施。
32位JVM和64位JVM之間存在一些明顯的區(qū)別和細(xì)微差別锄禽。我將嘗試通過此問答文章來澄清它們潜必。
我們是否需要了解32位JVM和64位JVM之間的區(qū)別?
如果你不是在構(gòu)建性能型Java服務(wù)沃但,則不必了解它們之間的區(qū)別磁滚。32位JVM和64位JVM之間的細(xì)微差別不會對你的Java服務(wù)產(chǎn)生太大影響。
64位JVM的性能是否優(yōu)于32位JVM宵晚?
我們大多數(shù)人認(rèn)為64位大于32位垂攘,因此64位JVM性能將優(yōu)于32位JVM性能。其實(shí)不然淤刃,事實(shí)并非如此晒他。與32位JVM相比,64位JVM的性能可能會有所下降钝凶。以下是Oracle JDK文檔中有關(guān)64位JVM性能的摘錄:
`
通常仪芒,與在32位VM上運(yùn)行同一應(yīng)用程序相比唁影,能夠處理大量內(nèi)存的好處是64位VM的性能損失較小耕陷。當(dāng)你遷移到64位VM時掂名,將在64位平臺上運(yùn)行的應(yīng)用程序與在SPARC上的32位平臺運(yùn)行的應(yīng)用程序相比,性能差異降低了10-20%哟沫。在AMD64和EM64T平臺上饺蔑,此差異范圍為0-15%,具體取決于訪問應(yīng)用程序所執(zhí)行的指針的數(shù)量嗜诀』”
如果性能受到影響,為什么有人會使用64位JVM隆敢?
在32位JVM中发皿,最大可尋址內(nèi)存空間僅為2 ^ 32(即?4gb)。這意味著Java進(jìn)程的最大內(nèi)存大小不能超過4GB拂蝎。實(shí)際上穴墅,由于各種其他限制(例如可用交換,內(nèi)核地址空間使用温自,內(nèi)存碎片和VM開銷)玄货,該限制要低得多。下表總結(jié)了可以在32位JVM上設(shè)置的最大堆大械棵凇(即-Xmx):
操作系統(tǒng) | 最大堆 |
---|---|
AIX | 3.25 GB |
Solaris | 2 ~ 4 GB |
Linux | 2 ~ 3 GB |
Windows | 1.5 GB |
Mac OS X | 3.8 GB |
而如果你在64位JVM上運(yùn)行應(yīng)用程序松捉,則最大可尋址內(nèi)存空間為2 ^ 64(即... 沒算出來--_--)。這意味著你的應(yīng)用程序的最大可尋址內(nèi)存大小接近無限馆里。
`
為什么64位JVM性能可能比32位JVM慢
這是由于以下事實(shí):系統(tǒng)中的每個本機(jī)指針占用的是8個字節(jié)而不是4個字節(jié)隘世。此額外數(shù)據(jù)的加載對內(nèi)存使用有影響,這取決于執(zhí)行過程中加載了多少個指針鸠踪,從而導(dǎo)致執(zhí)行速度稍慢以舒。
好消息是,由于以64位模式運(yùn)行的AMD64和EM64T平臺慢哈,Java VM獲得了一些額外的寄存器蔓钟,可用于生成更有效的本機(jī)指令序列。比較32位和64位執(zhí)行速度時卵贱,這些額外的寄存器將性能提高到通常根本沒有性能損失的地步滥沫。
從32位JVM遷移到64位JVM時需要考慮哪些事項(xiàng)?
GC Stop World時間
從32位JVM遷移到64位JVM的主要原因是要獲得較大的堆大屑恪(即-Xmx)兰绣。當(dāng)增加堆大小時,GC暫停時間會自動開始變長编振,因?yàn)楝F(xiàn)在內(nèi)存中有更多垃圾需要清除缀辩。在進(jìn)行遷移之前,你需要進(jìn)行適當(dāng)?shù)腉C調(diào)整,否則臀玄,你的應(yīng)用程序可能會經(jīng)歷幾秒鐘到幾分鐘的暫停時間瓢阴。于此同時,有一個專門的GC分析網(wǎng)站可以供你去配置使用GCeasy
Native library
如果你的應(yīng)用程序使用Java本機(jī)接口(JNI)訪問本機(jī)庫健无,那么你還需要升級Native library荣恐,因?yàn)?2位JVM只能使用32位Native library。同樣累贤,64位JVM只能使用64位Native library叠穆。
什么是CompressedOops?它與32位臼膏,64位JVM有關(guān)嗎硼被?
是的,CompressedOOps與32位和64位JVM有關(guān)渗磅。
我們用數(shù)據(jù)字段定義對象嚷硫。當(dāng)在內(nèi)存中創(chuàng)建該對象以及數(shù)據(jù)字段時,還將創(chuàng)建對象標(biāo)頭夺溢。JVM需要對象標(biāo)頭來執(zhí)行內(nèi)部處理论巍,虛擬方法調(diào)用,垃圾回收风响,鎖定等嘉汰。
在32位JVM中,此對象標(biāo)頭占用8個字節(jié)状勤;在64 位JVM中鞋怀,該對象標(biāo)頭占用16個字節(jié)。增加8個字節(jié)聽起來可能并不多持搜,但是鑒于你的應(yīng)用程序在其運(yùn)行時創(chuàng)建了數(shù)百萬個對象密似,將8個字節(jié)乘以數(shù)百萬個對象可能會增加可觀的開銷。
你可以通過傳遞XX:+ UseCompressedOops JVM參數(shù)來緩解此問題葫盼。當(dāng)你傳遞此參數(shù)時残腌,JVM會做出一個巧妙的技巧,并將對象標(biāo)頭的大小優(yōu)化為即使在64位中也僅使用12個字節(jié)贫导。只要你的JVM堆大信酌ā(即-Xmx)小于32GB,此技巧就會起作用孩灯。如果超過32 GB闺金,則對象標(biāo)頭大小將再次變?yōu)?6個字節(jié)。
注意:自Java SE 6u23及更高版本以來峰档,已將-XX:+ UseCompressedOops設(shè)置為默認(rèn)值败匹。僅當(dāng)你在JDK 6u23或更早版本上運(yùn)行時寨昙,才傳遞-XX:+ UseCompressedOopsargument。
什么時候應(yīng)該使用32位和64位JVM掀亩?
<2GB內(nèi)存
:如果你的應(yīng)用程序的堆大刑蚰摹(即-Xmx)小于2GB,則無需費(fèi)力地決定归榕。使用32位JVM尸红。
> 2GB內(nèi)存
:如果你的應(yīng)用程序需要2GB以上的內(nèi)存吱涉,那也不是明智的決定刹泄。使用64位JVM。但是怎爵,請進(jìn)行適當(dāng)?shù)男阅軠y試以衡量和減輕影響特石。
如何查找我的應(yīng)用程序是在32位還是64位JVM上運(yùn)行?
有一些選擇鳖链。讓我展示幾個選擇:
方法一:在命令提示符下姆蘸,發(fā)出命令:
java -version
如果是64位JVM,你將看到輸出包含單詞:“64-Bit”芙委。例:
java version "1.8.0_181"
Java(TM) SE Runtime Environment (build 1.8.0_181-b13)
Java HotSpot(TM) 64-Bit Server VM (build 25.181-b13, mixed mode)
如果它是32位JVM逞敷,則不會顯示單詞:“64-Bit”。例:
java version "1.8.0_211"
Java(TM) SE Runtime Environment (build 1.8.0_211-b12)
Java HotSpot(TM) Client VM (build 25.211-b12, mixed mode)
方法二:你從Java程序發(fā)出以下語句:
System.out.println(System.getProperty("sun.arch.data.model") + "-bit JVM");
根據(jù)JVM類型灌侣,適當(dāng)?shù)陌姹緦⒈淮蛴≡诳刂婆_上推捐。
我可以在64位操作系統(tǒng)上運(yùn)行32位JVM嗎?
有32位OS和64位OS侧啼。如果你在32位操作系統(tǒng)上運(yùn)行(這在今天很難找到)牛柒,則只能運(yùn)行32位JVM。另一方面痊乾,如果你在64位操作系統(tǒng)上運(yùn)行皮壁,則可以在32位JVM或64位JVM上運(yùn)行應(yīng)用程序。
如何下載32位JVM或64位JVM哪审?
轉(zhuǎn)到Oracle JDK下載頁面時蛾魄,將看到用于下載特定于你的操作系統(tǒng)的JDK的選項(xiàng):
如果你選擇x86,則將在此處下載32位JVM湿滓。如果選擇x64滴须,則將下載64位JVM。
在32位JVM上編譯的代碼可以在64位JVM上運(yùn)行嗎茉稠?
我們使用javac即java編譯器將Java代碼編譯為字節(jié)代碼(即* .class文件)描馅。生成的字節(jié)碼與32位和64位JVM無關(guān)。它可以在兩個JVM上運(yùn)行而线。記住Java古老的諾言:“Write once, run anywhere”铭污。