起因

服务挂了,第一时间下载自动生成的内存快照,用Mat打开进行分析
等待分析完成后选择Leak Suspects Report(泄露嫌疑人报告)
Leak Suspects Report(泄露嫌疑人报告)

分析完成直接找到第一个嫌疑人
enter description here
可以看到嫌疑人的类名是:org.hibernate.internal.SessionFactoryImpl,肯定和hibernate脱不了关系了.
点击Details查看详情
直接查看Accumulated Objects in Dominator Tree(查看引用树中的对象)
enter description here
可以看出来是org.hibernate.internal.util.collections.BoundedConcurrentHashMap的Segment占用内存太大导致了,这个时候可以点击org.hibernate.internal.util.collections.BoundedConcurrentHashMap>list Objects>with outgoing references 查看他下面的引用
小科普一下:BoundedConcurrentHashMap是支持检索的完全并发和可调整的预期更新并发的哈希表,在hibernate中作为sql的缓存使用即QueryPlanCache.
enter description here
找个看起来最大的Retained Heap一路点下去
enter description here

追到最底层发现一个java.util.HashMap,和String 占用内存比较大,这个String明显存的是sql,我们拿出去看一眼,右键value>copy>value,粘到记事本
enter description here
好家伙,不用分析了,找到写这个sql的开发杀了祭天就行了.
sql头:
enter description here
sql尾:
enter description here
这么长的sql,全是not in的参数,查代码发现业务是这样的
查出没被关联过的订单
这个老哥的思路是
查出所有被关联过的订单,not in一下再查数据库 查出来的就是没被关联过的订单
emmmm nb!

查询其他的大内存对象,发现都是这个功能的sql缓存,直接改功能实现,发布,解决问题.