记一次线上排查内存泄漏的问题

事件描述:系统task任务隔断时间经常无缘无故停止执行。

事件分析:1.单线程task由于线程阻塞,导致无法执行下一个task调度任务。每次都是通过重启应用进行解决。

但是阻塞的话有一个特店,一般情况下只会导致某个任务停止,不可能所有的task都会不执行,因此此点排除。

2.那会是什么原因?还会有什么情况会导致这个问题?因此想起了还有一种情况会导致这样的问题发生。那就是java虚拟机在执行fullgc的时候。稍后会简单介绍下相关知识。经通过排查,确认是由于内存泄漏,导致系统进行频繁fullgc导致的,稍后会具体介绍排查步骤以及解决方式。

3.什么是内存泄漏以及fullgc?

java的对象主要保存在内存中,如果对象不停的创建,则会占据越来越多的内存空间,而内存空间是有限的,长此以往,肯定会造成内存不足。因此java虚拟机需要进行对象的垃圾回收。java虚拟机会将不在使用的对象进行回收以释放内存空间,如果某些对象一直不能被java虚拟机回收,则会将其放入old区,如果这样的对象越来越多,则old区则会越来越大,如果old区的大小超过一定的阈值则会触发fullgc,java虚拟机在进行fullgc的时候,会暂停系统中所有线程的执行,专心来做fullgc,如果fullgc一直回收不掉,则会一直进行下去,这样的话就会导致系统所有线程都执行不了。(因此fullgc的次数越少,系统越稳健)内存泄漏:因为一直有对象回收不掉,导致系统可用内存越来越小,顾名思义好像内存空间泄漏了一样。这就是问题导致的原因,关于java虚拟机以及内存管理这块,可以参考【深入理解java虚拟机】这本书,这里不再详细赘述。

4.排查步骤:通过jmap -heap+进程号每天监控java内存使用状况,发现old区每天都在换换增加,当增加到99%时,系统task任务停止的情况发生了。因此可以确定问题已经找到,通过jmap-dump命令生成一个dump文件,copy到本地用Eclipse的mat工具进行分析发现sessionFactory对象占据过大,因此可以确定罪魁祸首便是他,通过展开这个对象的树形结构发现这里面有一个queryplancache对象占据过大,这个对象里存入的都是sql语句,本项目由于比较老化,持久层框架用的是hibernate,通过分析得知hibernate为了效率会缓存产生的sql语句,如果不进行缓存那么每次都要将hql或者实体映射转换成sql语句去请求数据库,这样太耗费性能,因此需要将转换的sql缓存起来,如果下一次遇到一样的查询,直接用缓存的sql去请求数据库这样的话可以提高性能。而hibernate缓存sql以及映射sql语句的条件中有一项是根据sql语句的参数来进行判定,如果没有用到占位符进行参数映射的话,hibernate都会认为是一条全新的数据,会将其缓存,因此对象会越来越大。

 

5.解决方案:将所有的参数映射改为占位符方式,这样的话,相同的参数查询只会缓存一条,同时将queryplancache的大小设置为一个比较小的值,默认为2048,其实是一种空间浪费。改完后部署上线。

6.每天监控内存使用情况,发现内存状况一切正常,而该种也没有再重现过,至此问题解决。

 

 

线上内存飙升是一个比较严重的问题,如果不及时处理,可能会导致系统崩溃。以下是一般的排查问题的过程: 1. 监控告警分析:系统应该有监控告警机制,如果内存使用率过高,应该及时发出告警并录监控数据。首先,需要分析告警信息和监控数据,确认内存使用率确实出现了异常。 2. 定位问题代码:通过监控工具、日志和代码调试等方法,确定哪些代码出现了内存使用率飙升的问题。可以使用 JVM 的内存分析工具,例如 jmap、jhat、jstack、VisualVM 等来分析内存使用情况,并找出内存泄漏的代码位置。 3. 解决问题代码:根据定位出的代码问题,进行修复。对于内存泄漏问题,需要分析代码中的对象生命周期,释放不再使用的对象,并检查是否存在对象引用未释放的情况。对于频繁创建和销毁对象、大对象等问题,需要优化代码逻辑,减少内存占用。 4. 测试验证:完成修复后,需要进行测试验证,确保问题得到了解决,并且没有引入新的问题。 5. 监控预警优化:针对该问题,需要优化监控预警机制,避免类似问题再次出现。可以增加更加详细的监控数据、设置更加敏感的告警阈值等等。 总之,线上内存飙升是一个比较严重的问题,需要及时发现、定位、修复和验证。同时,也需要优化监控预警机制,避免类似问题再次出现。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值