1、通過(guò)top查看高CPU進(jìn)程情況
# top
2、使用jstack命令導(dǎo)出線(xiàn)程信息
# jstack 線(xiàn)程PID > jstack_result.log
3、查看問(wèn)題進(jìn)程下的線(xiàn)程情況
# top -H -p 線(xiàn)程PID
4、將十進(jìn)制的高CPU線(xiàn)程編號(hào)轉(zhuǎn)換為十六進(jìn)制備用
# printf "0x%x\n" 線(xiàn)程PID
5、在jstack_result.log信息中查找十六進(jìn)制線(xiàn)程編號(hào),查找問(wèn)題。以?xún)蓚€(gè)線(xiàn)程5709[0x164d],5710[0x164e]為例:

6、查看進(jìn)程內(nèi)存情況
# jmap -dump:format=b,file=jmap.hprof 線(xiàn)程PID
- 導(dǎo)出內(nèi)存快照,然后下載下來(lái),用MAT打開(kāi)
7、下載安裝MAT
- 下載地址:Eclipse Memory Analyzer Open Source Project | The Eclipse Foundation
-
啟動(dòng)如果對(duì)JDK版本有要求,可以安裝新JDK,不用修改環(huán)境變量直接修改配置文件MemoryAnalyzer.ini
-
如果加載heap_dump文件內(nèi)存不夠,可以修改配置文件MemoryAnalyzer.ini
-
MAT內(nèi)存分析展示
8、這次排查結(jié)果就是org.hibernate.engine.query.spi.QueryPlanCache 占用了大量空間
6.png
hibernate中的QueryPlanCache會(huì)緩存sql,QueryPlanCache占用多大,基本上歸結(jié)為IN子句中具有可變數(shù)量的值,而Hibernate試圖緩存這些查詢(xún)計(jì)劃。如果in子句后面跟不同數(shù)量或數(shù)值,都會(huì)增加一條緩存(業(yè)務(wù)中確實(shí)有這么一條根據(jù)id進(jìn)行記錄更新操作)。從而緩存大量的sql導(dǎo)致heap內(nèi)存溢出。
解決方案:
在application.properties文件增加以下配置:
spring:
jpa:
properties:
hibernate:
query:
plan_cache_max_size: 64
plan_parameter_metadata_max_size: 32
plan_cache_max_soft_references: 1024
plan_cache_max_strong_references: 64
in_clause_parameter_padding: true



