記一次idea效能調優
到這裡,其實我已經猜出問題出在哪裡了,是日誌!因為我以前把控制檯的輸出設定為無限制,而為了本地除錯方便,我又把hibernate的日誌也列印了出來,在執行單個案例的時候並不明顯,而如果執行大量案例執行,這個日誌的量就非常大了,多次壓測1000訪問量後系統產生大量日誌,這些日誌都被作為文字類的內容被儲存了起來,又因為我把控制檯日誌設為無限,idea不清除這些類物件,最終導致物件越來越大,拖垮了idea。
如果檢測的不是idea而是自己的程式,那麼還可以繼續通過histogram跟dominator_tree進行跟蹤。因為強引用、軟引用、弱引用跟虛引用只有強引用不會被gc,如果多次gc沒有回收掉,肯定有強引用在關聯這個物件,通過支配樹dominator_tree(展示物件層級關係跟記憶體佔用百分比)跟Merge Shortest Paths to GC Roots(展示gc樹引用關係圖)可以慢慢找到強引用的所在,從而定位記憶體溢位原因。
MAT工具的使用參考: ofollow,noindex" target="_blank">https://www.javatang.com/archives/2017/11/08/11582145.html
定位了問題後,稍後又對idea的各個引數進行了一次調整,因為預設的配置相對來說低了點,參考: https://segmentfault.com/a/1190000010144588
4、引數修正
明白了問題所在,那麼進行修復並測試,修改idea的相關引數配置為:
-Xms512m -Xmn512m -Xmx2048m -XX:ReservedCodeCacheSize=240m -XX:+UseCompressedOops -Dfile.encoding=UTF-8 -XX:+UseG1GC//使用G1收集器,好處是並行收集 -XX:+UseNUMA//優先使用速度較快的記憶體 -XX:SoftRefLRUPolicyMSPerMB=50 -ea -Dsun.io.useCanonCaches=false -Djava.net.preferIPv4Stack=true -Djdk.http.auth.tunneling.disabledSchemes="" -XX:+HeapDumpOnOutOfMemoryError -XX:-OmitStackTraceInFastThrow -Xverify:none -XX:ErrorFile=$USER_HOME/java_error_in_idea_%p.log -XX:HeapDumpPath=$USER_HOME/java_error_in_idea.hprof -javaagent:JetbrainsCrack-3.1-release-enc.jar
主要是將堆記憶體最小設為512,最大為2G,變為了原來的3倍,然後把gc演算法改為了G1,並優化記憶體讀取為NUMA。NUMA我也不熟悉,網上查到的結果如下:
numa 是一個 CPU 的特性。SMP 架構下,CPU 的核是對稱,但是他們共享一條系統匯流排。所以 CPU 多了,匯流排就會成為瓶頸。在 NUMA 架構下,若干 CPU 組成一個組,組之間有點對點的通訊,相互獨立。啟動它可以提高效能。
NUMA 需要硬體,作業系統,JVM 同時啟用,才能啟用。Linux 可以用 numactl 來配置 numa,JVM 通過-XX:+UseNUMA來啟用。
5、執行,檢視結果
按照以上步驟,同樣程式啟動後執行兩次請求數量均為1000的壓測,jconsole如圖:
兩次明顯的記憶體增長跟cpu消耗,監控器看到的記憶體情況:
相比之前,idea的記憶體增長到了2.5G,cpu在壓測結束後恢復正常。點選idea使用,沒有在發生卡頓的情況,可知的確是日誌導致idea卡頓的。而當時idea的cpu消耗亦很高,應該是頻繁gc所致。
當然,我僅僅這麼修改是肯定不行的,如果控制檯仍舊是無限,那麼總有一天還是會oom的,我目前是手動清空控制檯,發現效果也還可以,會有效。如果不手動清空,則一定要設定控制檯最大行數,或者記憶體值,防止因日誌而導致的idea卡死現象。
--------------------------------------------------------------------------
對jconsole的使用並不熟練,如有錯誤之處請留言指正,多謝多謝。