記一次OOM問題排查過程
阿新 • • 發佈:2020-06-24
這周生產環境出了久違的
java.lang.OutOfMemoryError: Java heap space
,花了些時間找了下原因,記錄分享一下 ?
OOM分析
之前的jvm優化的文章中,有提到要增加-XX:+HeapDumpOnOutOfMemoryError -XX:HeapDumpPath=/data/logs/login/gc
,這對於排查問題非常有幫助,當發生OOM時就會輸出堆的記憶體快照(hprof檔案)。
從生產環境拷貝出hprof檔案後,就可以用MAT或者Jvisualvm來分析了,相對來說MAT更智慧和易用一些。
用MAT開啟hprof檔案後,很明顯可以看到(這裡補充一個小插曲:在jdk11的環境下,MAT會報錯無法開啟,建議切回jdk8的環境開啟MAT)
通過Leak Suspects其實已經可以看出問題所在了,SessionFactoryImpl
這個例項佔用了87.48%的記憶體。很明顯是記憶體洩漏了。
我們開啟Histogram,可以看到類的例項數和所佔的記憶體
這個看起來還並不是很清晰,可以排除軟,弱,虛引用(剩下強引用)看的更加直觀
現在就很明顯了,SessionFactoryImpl
中的QueryPlanCache
造成了記憶體洩漏
QueryPlanCache記憶體洩漏解決
那什麼是QueryPlanCache
呢,hibernate中的QueryPlanCache
會快取sql,以便於後邊的相同的sql重複編譯。
如果in後的引數不同,hibernate
所以可以通過設定快取最大值來進行限制,不設定預設是2G。
spring:
jpa:
properties:
hibernate:
query:
plan_cache_max_size: 64
plan_parameter_metadata_max_size: 32
複製程式碼