1. 程式人生 > 程式設計 >記一次OOM問題排查過程

記一次OOM問題排查過程

這周生產環境出了久違的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%的記憶體。很明顯是記憶體洩漏了。

MAT-1

我們開啟Histogram,可以看到類的例項數和所佔的記憶體

MAT-1

這個看起來還並不是很清晰,可以排除軟,弱,虛引用(剩下強引用)看的更加直觀

MAT-1

現在就很明顯了,SessionFactoryImpl中的QueryPlanCache造成了記憶體洩漏

MAT-1

QueryPlanCache記憶體洩漏解決

那什麼是QueryPlanCache呢,hibernate中的QueryPlanCache會快取sql,以便於後邊的相同的sql重複編譯。

如果in後的引數不同,hibernate

會把其當成不同的sql進行快取,從而快取大量的sql導致heap記憶體溢位。

所以可以通過設定快取最大值來進行限制,不設定預設是2G。

spring:
  jpa:
    properties:
      hibernate:
        query:
          plan_cache_max_size: 64
          plan_parameter_metadata_max_size: 32
複製程式碼

Github 不要吝嗇你的star ^.^
更多精彩 戳我