一次内存溢出事故 |
您所在的位置:网站首页 › jprofiler工具引起gc时间变长 › 一次内存溢出事故 |
事情经过
事情是这样,公司项目是一个springcloud的微服务,服务每隔半个月就会发生一次频繁的fullGC。后来定位到是缓存不合理导致的,该缓存的key是一条条sql,value是表名。这个缓存是用来干嘛呢?查了下他主要是分库组件sharding-jdbc在执行sql时,首先要通过这个缓存来获取sql对应的表。这个缓存设计的大小是1000,超时时间1天,而且用的一个LocalCache是强引用。因为在我们的生产环境中经常会有一下批量插入查询的操作,一个插入一千条数据的sql放在这个地方,就可能是一个 2.5MB左右的字符串。也就说极端情况,如果有几百条这种大sql被缓存进来,那么一下子就会占用1G的内存,而我们的应用堆大小只有5个GB,所以悲剧时不时就发生了。后来发了个邮件给架构组同事,修改了这部分代码,把sql变成sql的hashCode,问题就解决了。 jprofiler 使用过程分析出来后原因是挺简单的,这里记录一下用到的工具jprofiler,如何用jprofiler分析GCRoot。首先用jmap获取java进程的dump文件,命令如下: jmap -dump:live,format=b,file=dump.hprof 5092然后,用jprofiler导入dump文件,按照下图顺序点击,在弹出的窗口选择上面用jmap生成的文件即可。 在整个分析溢出异常的过程中,基本的思路是有的: 1.保存异常现场(jmap获取dump文件),生产环境中如果由多个微服务部署,可以直接dump,否则的话还是要先重启,保证生产,再想办法再测试环境复现问题。 2.jprofiler分析大对象的持有者。 3.结合代码进行优化。 在分析过程中,我更多的时间反而是花在了工具学习上,期间尝试过Jvisualvm(java自带的),发现不太好用。后来换成了jprofiler。 最后发现原因后,成就感是满满的,感觉自己不光是在CRUD了~~ |
CopyRight 2018-2019 办公设备维修网 版权所有 豫ICP备15022753号-3 |