爲什麼需要調優
前提
好馬配好鞍,好車配好發動機。比如超級跑車上給安裝一個時風三輪車的發動機是十分不合理的。JVM調優主要是根據所選的垃圾收集器,對一些參數合理性的優化,以確保程序在JVM中能以最優的方式運行。
調優場景及實戰
結合作者公司實際場景來給大家介紹參數如何設置,公司做的產品互聯網金融方面的,要求支持高併發,垃圾收集器選擇的是CMS(Concurrent Mark Sweep),這個收集器的好處是併發收集,停頓低。但是缺點也很明顯CPU敏感,浮動垃圾,產生內存碎片。這塊就不過多解釋這幾個名詞的意思,接下來進入正題,我們的生產環境上是如何合理配置參數的。首先我們採用的配置方式是把這些參數都寫入環境變量中,項目啓動前會先加載這個腳本,將參數信息設置到環境變量中,然後執行啓動腳本。下面是參數的詳細介紹
-
-Xms -Xmx -Xss
Xms:JVM啓動時申請的最小堆內存大小,當空餘堆內存大於70%,JVM會減少堆內存直到最小限制
Xmx:JVM啓動時申請的最大堆內存大小,當空餘堆空間小於40%,JVM會增大堆內存直到最大限制
通常情況下爲了防止內存抖動(減小或者增大會有一定的性能開銷)Xms和Xmx一般設置成相同。Xss:每個線程的堆棧大小,一般根據應用的線程所需內存大小進行調整。大多數情況下設置爲1M就可以了
-
-XX:+UseBiasedLocking
是否開啓偏向鎖,默認是開啓的,有一些項目多線程之間競爭鎖資源比較頻繁,所以會禁用偏向鎖。
-
-XX:PermSize -XX:MaxPermSize(JDK1.8已經無效)
PermSize:JVM初始分配的非堆內存(PS:非堆內存一般指方法區)
MaxPermSize:JVM最大允許分配的非堆內存,按需分配
JVM官方文檔中提到過 ,非堆內存區是可以選擇不被java垃圾回收機制處理的地方。不合理的配置會產生 OutOfMemoryError:PermGen space,這個是java中常見的OOM之一。舉個產生會產生此異常的例子,需要加載很多class到容器中。
-
-XX:+DisableExplicitGC
DisableExplicitGC:開啓會自動將System.gc()調用轉換成一個空操作。目的爲了防止有人在代碼中進行調用,從而會產生Full GC。
-
-XX:+UseConcMarkSweepGC
UseConcMarkSweepGC:設置年老代爲併發收集,通俗來說就是使用CMS垃圾收集器
-
+UseParNewGC
UseParNewGC:設置年輕代爲並行收集。可與CMS收集同時使用。一般高併發的項目中都會採用CMS+ UseParNew的方式來配置垃圾收集器
-
-XX:+CMSParallelRemarkEnabled
CMSParallelRemarkEnabled:開啓並行收集,降低標記停頓
-
-XX:+UseCMSCompactAtFullCollection
UseCMSCompactAtFullCollection:打開對老年代的壓縮。可能會影響性能,但是可以消除內存碎片。
-
-XX:LargePageSizeInBytes
LargePageSizeInBytes:設置內存頁的大小,一般不易設置過大,會影響到Perm的大小
-
-XX:+UseFastAccessorMethods
UseFastAccessorMethods:原始類型的快速優化
-
-XX:+UseCMSInitiatingOccupancyOnly
UseCMSInitiatingOccupancyOnly: 使用手動定義初始化定義開始CMS收集,避免hostspot虛擬機來自行觸發CMS GC
-
-Djava.awt.headless=true
Djava.awt.headless:一般開啓,系統的配置模式,說得是如果系統可能缺少顯示設備、鍵盤或鼠標這些外設的情況下可以使用該模式。
-
-Djava.security.egd=file:/dev/./urandom
Djava.security.egd:加快隨機數的產生過程,因爲Tomcat的會話ID都是隨機生成的,配置此項後可以加快項目啓動速度,
總結
JVM參數雖然衆多,但基本上大多數都不需要自行修改,JDK新版本在優化後也會大批量減少很多參數。
最後說一句,大家發現有配置不合理的地方可以提出來,一塊討論,以上純手敲,碼字不易,且讀且珍惜。