這是我在企業軟件開發生涯中多次遇到的問題。 我不得不每隔一段時間就提供有關配置特定新環境的建議。
而且,很多時候,手頭的問題與“我應該使用32位或64位JVM”有關。 老實說,一開始我只是擲硬幣。 而不是給出合理的答案。 (對不起,兄弟!)但是到目前為止,我已經對此進行了更多的了解,并希望與您分享。 第一站–越多越好。 對? 所以–當64> 32時,這很容易 答:如果可能,請始終選擇64位? 好吧,抱著你的馬。 64位體系結構的缺點是相同的數據結構會消耗更多的內存。 多很多。 我們的測量表明,根據JVM版本和操作系統版本以及硬件體系結構,最終使用的堆比32位多使用30-50%。 較大的堆還可能導致較長的GC暫停,從而影響應用程序延遲-在4.5GB的堆上運行完整的GC肯定比在3GB的堆上花費更長的時間。 因此,僅僅因為64比32大就跳到64位潮流上是不正確的。
但是……您什么時候才想要使用64位JVM? 在大多數情況下,原因是堆大。 在不同的體系結構上,您很快就會遇到32位體系結構上最大堆大小的限制。 下面說明了不同平臺上的這些限制:
操作系統 | 最大堆 | 筆記 |
---|---|---|
的Linux | 2GB | 在特定的內核上有3GB的空間,例如hugemem |
視窗 | 1.5GB | 帶有“ / 3GB”啟動標志和通過/ LARGEADDRESSAWARE開關編譯的JRE的最大3GB) |
Mac OS X | 3.8GB | 警報-找不到古老的Mac,因此未經我測試 |
現在怎么這么糟? 畢竟,我敢打賭,您已經看到32位計算機在16G + RAM上運行并且運行良好。 JVM在Windows上分配的內存不足此16G的10%怎么了?
主要原因–地址空間。 理論上,在32位系統中,每個進程最多可以分配4GB的內存。 在Windows上打破這一點的是如何處理進程地址空間。 Windows將進程地址空間減少一半。 其中一半保留給內核(用戶進程無法使用),另一半保留給用戶。 盒子中有多少RAM無關緊要,一個32位進程只能使用2GB RAM。 更糟糕的是,該地址空間必須是連續的,因此在實踐中,Windows機頂盒通常只剩下1.5-1.8GB的堆空間。
您可以使用32位窗口來減少內核空間并增加用戶空間,這是一個技巧。 您可以在boot.ini中使用/ 3GB參數。 但是,要實際利用此機會,必須使用/ LARGEADDRESSAWARE開關來編譯/鏈接JVM。
不幸的是,至少對于Hotspot JVM并非如此。 直到最新的JDK 1.7版本,才使用此選項編譯JVM。 如果您在2006年后版本的jRockit上運行,則更加幸運。 在這種情況下,您可以享受高達2.8-2.9GB的堆大小。
那么–我們可以得出結論,如果您的應用程序需要超過2-3GB的內存,那么您應該始終在64位上運行嗎? 也許。 但是您也必須意識到這些威脅。 我們已經介紹了罪魁禍首–增加了堆消耗,并延長了GC暫停時間。 讓我們在這里分析原因。
問題1:在64位上需要30-50%的更多堆
為什么這樣? 主要是由于64位體系結構中的內存布局。 首先–在64位JVM上,對象標頭是12個字節。 其次,對象引用可以是4個字節,也可以是8個字節,具體取決于JVM標志和堆的大小。 與32位標頭上的8個字節和引用標本上的4個字節相比,這無疑增加了一些開銷。 您還可以深入研究我們的較早文章之一,以獲取有關計算對象的內存消耗的更多信息。
問題2:較長的垃圾收集暫停時間
建立更多的堆意味著GC在清除未使用的對象時還有更多工作要做。 在現實生活中,這意味著在構建大于12-16GB的堆時,您必須格外小心。 無需進行微調和測量,您就可以輕松引入幾分鐘的完整GC暫停時間。 在延遲不是很關鍵并且您可以優化吞吐量的應用程序中,這可能沒問題,但是在大多數情況下,這可能會成為熱門。
那么,當我需要更大的堆并且不希望引入由64位體系結構引起的開銷時,該怎么辦? 在我們較早的博客文章中 ,我們介紹了幾種技巧–您可以通過堆分區,GC調整,在不同的JVM上構建或在堆外分配內存來擺脫困境。
最后,讓我們重申一下,您應該始終了解選擇64位JVM的后果。 但不要害怕此選項。
參考: 應該使用32位還是64位JVM? 從我們的JCG合作伙伴 Vladimir Sor在Plumbr Blog博客上獲得。
翻譯自: https://www.javacodegeeks.com/2012/12/should-i-use-a-32-or-a-64-bit-jvm.html