Java项目内存占用过大宕机问题
记一次java项目占用内存过大,导致项目无限重启的情况.
内存一直增加,并且不释放,就导致了服务器一直处在宕机的状态下,简单记录一下定位问题的几个关键知识点.
1.使用top命令查询占用内存和cpu较大的线程
2.查询后会获得一个PID的线程,使用jmap -histo pid 可以查看当前Java进程创建的对象数目和占用内存大小
jmap -histo:live [pid] 还有一个查询活跃对象的,这个命令执行以后,会执行一次GC的操作
3.jmap -dump:live,format=b,file=xxx.xxx [pid] 使用这个命令可以导出堆栈的信息,以便于我们具体分析问题
导出来以后需要利用Eclipse Memory Analyzer Tool(MAT)分析内存泄漏,MAT工具大家可以自行在百度上搜索下载即可.
简单看一下这个工具的用途:
这是导入堆栈信息之后的MAT界面,首先是一个overview,红框里面的基本上就是我们要使用到的.
点击report下面的Leak Suspects,MAT工具会列出来一个异常的报告,大家可以根据这个来分析问题
detail里面可以看到比较详细的链路信息
org.hibernate.internal.SessionFactoryImpl这个类,查询数据映射到map的数据结构上,但是这个数据是hibernate的缓存数据,我们并不会直接使用的.
点到detail里面可以看到:
这个是累计对象数量,从这里我们就可以看出来是Hibernate的缓存计划导致的.
解决方案可以参考https://hibernate.atlassian.net/browse/HHH-5300
最终的解决方案:
设置缓存最大值,而不是采用hibernate默认的值,就可以解决问题.
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