App下載

JVM的Xms和Xmx參數(shù)設(shè)置為什么要設(shè)置為相同值

猿友 2020-09-08 10:27:39 瀏覽數(shù) (8504)
反饋

文章轉(zhuǎn)載自公眾號(hào):程序新視界

最近正在重新學(xué)習(xí) JVM 的內(nèi)存結(jié)構(gòu)及相關(guān)優(yōu)化內(nèi)容,無意中看到 IDEA 的 VM 配置(安裝時(shí)默認(rèn)配置)中有如下的配置:

# custom IntelliJ IDEA VM options


-Xms2048m
-Xmx2048m

看到 Xms 和 Xmx 的參數(shù)設(shè)置一樣,是不是稍微有些奇怪?這里就寫篇文章分析一下,JVM 的 Xms 和 Xmx 參數(shù)設(shè)置為相同的值有什么好處?首先來了解一下相關(guān)參數(shù)的概念及功能。

Xms和Xmx參數(shù)定義

在啟動(dòng) Java 應(yīng)用程序時(shí),我們通??梢酝ㄟ^參數(shù)XmsXmx來配置 JVM 的堆信息。不配置雖然會(huì)有默認(rèn)值,但如果受硬件所限或需對(duì) JVM 進(jìn)行調(diào)優(yōu),則需要根據(jù)情況指定這兩個(gè)參數(shù)的值。

-Xms:堆內(nèi)存的最小Heap值,默認(rèn)為物理內(nèi)存的1/64,但小于1G。默認(rèn)當(dāng)空余堆內(nèi)存大于指定閾值時(shí),JVM 會(huì)減小heap的大小到-Xms指定的大小。

-Xmx:堆內(nèi)存的最大Heap值,默認(rèn)為物理內(nèi)存的1/4。默認(rèn)當(dāng)空余堆內(nèi)存小于指定閾值時(shí),JVM 會(huì)增大Heap-Xmx指定的大小。

內(nèi)存情況的變化

常規(guī)的JVM參數(shù)使用如下:

java -Xms512m -Xmx1g

在這種配置下,JVM 啟動(dòng)時(shí)會(huì)分配512M的堆內(nèi)存空間,隨著程序的執(zhí)行,所需的堆空間越來越大,則會(huì)逐漸增大堆內(nèi)存空間,直到Xmx參數(shù)指定的堆最大空間1G。

當(dāng)堆內(nèi)存使用率降低,則會(huì)逐漸減小該內(nèi)存區(qū)域的大小。整個(gè)過程看似非常合理,但為什么很多生產(chǎn)環(huán)境卻也將兩個(gè)值配置為相同的值呢?

JVM垃圾回收的不足

當(dāng)堆內(nèi)存使用情況變化時(shí),并不是單純的擴(kuò)大和縮小堆內(nèi)存就完事了。在此之前還會(huì)執(zhí)行GC(垃圾回收)操作。如果-Xms起初值設(shè)置的比較小,那么就頻繁觸發(fā)GC操作。當(dāng)GC操作無法釋放更多內(nèi)存時(shí),才會(huì)進(jìn)行內(nèi)存的擴(kuò)充。

我們都知道GC操作是需要耗時(shí)的,而且Full GC會(huì)引起“Stop the World”,也就是說會(huì)引起線程停止,不可避免就會(huì)引起性能問題。

相同值的好處

面對(duì)上面的問題,為了避免在生產(chǎn)環(huán)境由于heap內(nèi)存擴(kuò)大或縮小導(dǎo)致應(yīng)用停頓,降低延遲,同時(shí)避免每次垃圾回收完成后JVM 重新分配內(nèi)存。所以,-Xmx-Xms一般都是設(shè)置相等的。

當(dāng)然,如果生產(chǎn)系統(tǒng)上線前有一段預(yù)熱時(shí)間的話,也可以不設(shè)置相等。對(duì)于需要高吞吐量的應(yīng)用來說,可以不在乎這種停頓,比如一些后臺(tái)的應(yīng)用之類,那么內(nèi)存可以適當(dāng)調(diào)大一些。(停頓時(shí)間越長(zhǎng),吞吐量反而越大),需要根據(jù)具體情況權(quán)衡。

其實(shí)關(guān)于在生產(chǎn)環(huán)境中把XmsXmx設(shè)為相同值也是 Oracle 官方推薦的。在Xms的參數(shù)描述中有這樣一段話:

Oracle recommends setting the minimum heap size (-Xms)equal to the maximum heap size (-Xmx) to minimize garbage collections.

其實(shí)這里還有一個(gè)小前提,那就是生產(chǎn)環(huán)境往往一臺(tái)服務(wù)器或一個(gè)容器只有一個(gè)服務(wù),獨(dú)占服務(wù)器意味著沒有必要調(diào)整 JVM 大小,每次調(diào)整反而會(huì)加大開銷。只有在多開發(fā)環(huán)境,比如個(gè)人電腦等運(yùn)行進(jìn)程比較多時(shí),動(dòng)態(tài)調(diào)整JVM才有必要。

注意事項(xiàng)

其實(shí)雖然設(shè)置為相同值有很多好處,但也會(huì)有一些不足。比如,如果兩個(gè)值一樣,會(huì)減少 GC 的操作,也意味著只有當(dāng) JVM 即將使用完時(shí)才會(huì)進(jìn)行回收,此前內(nèi)存會(huì)不停的增長(zhǎng)。

并且同一 JDK 的 GC 策略也有很多種,不能一概而論。另外,對(duì)于Hotspot虛擬機(jī),XmsXmx設(shè)置為一樣的,可以減輕伸縮堆大小帶來的壓力。但對(duì)于IBM虛擬機(jī),設(shè)置為一樣會(huì)增大堆碎片產(chǎn)生的幾率,并且這種負(fù)面影響足以抵消前者產(chǎn)生的益處。

小結(jié)

最近研究 Java 虛擬機(jī)比較多一些,越研究發(fā)現(xiàn)越有意思,越研究發(fā)現(xiàn)很多之前沒弄明白的問題都慢慢融會(huì)貫通了。強(qiáng)烈建議大家有時(shí)間的話讀讀相關(guān)的書籍,研究一些用法的底層邏輯。

以上就是W3Cschool編程獅關(guān)于JVM的Xms和Xmx參數(shù)設(shè)置為什么要設(shè)置為相同值的相關(guān)介紹了,希望對(duì)大家有所幫助。

0 人點(diǎn)贊