某日线上一个服务cpu突然升高,通过top -H命令查询到是一个线程占用cpu很高,
使用jstat -gc <pid>查询gc情况发现老年代使用量占满,一直在进行full gc,基本可以断定是由于这个原因导致cpu飙升。
需要找出老年代占满的原因
通过jmap -histo:live pid | head -10 查询当前线程在内存堆中的对象前10个发现里面存在几十万个pojo实例
导出整个JVM 中内存信息 jmap -dump:format=b,file=文件名 [pid]
使用MemoryAnalyzer导入文件后发现有内存泄漏,发现有线程池占用大量内存,查看详情后发现阻塞队列中存在上述pojo对象占用大量内存
查看线程池代码发现是因为线程池核心线程为1,导致大量请求积压在阻塞队列中,导致对面不能被回收,占用老年代,
修改线程池参数,重新启动服务观察多天后未复现该问题。