问题记录---java程序内存溢出

系统并发测试时因Java堆区内存溢出导致崩溃。通过监控工具定位到由String[]类型数据不断积累引起的内存泄漏问题,最终修复并确保了系统稳定性。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

    前段时间公司更新了新版本的业务系统,并进行了并发测试,并发数仅为20人左右,测试跑到3天左右,系统就开始奔溃了,查看日志信息。错误如下:

 

系统使用了thrift框架来进行服务的发布,从日志中可以看出由于java.lang.OutOfMemoryError: GC overhead limit exceeded原因导致了thrift服务端负责select线程的异常退出,服务端无法接受到请求。出现异常的thrift的源码如下:


   通过查找资料得出,GC overhead limit exceeded 是JVM定义的一个策略,通过统计GC时间来预测是否要OOM了,提前抛出异常,防止OOM发生。因为GC发生在堆区,所以得出结论为,Java堆区内存溢出导致程序异常。所以当天早上9点重新启动项目进行并发测试,并使用了jvisualvm工具(jvisualvm工具为jdk自带的图形化的jvm性能监控工具)对程序JVM的内存区域进行了监控。发现随着时间的增长,其堆内存增长迅速,在当天下午7点的时候堆内容已经从开始的50M左右增长到600多M。经过对比分析不同时间生成的堆转储文件,发现内存中存在持续增长且不被回收的String[]类型的数据,后期甚至占据堆内存的85%以上。对系统的代码进行分析发现,原本计划只在应用启动时加载一次的元素为String[]的List,由于程序的疏忽(懒加载未赋值,重复判空),导致随请求数被重复加载,List为static变量,被不断的add数据,却不能被回收,导致其占据大量的堆内存。对程序进行修改后,再重新进行测试,堆内存的占用一直稳定在60M上下,且未发现体积异常未被回收的对象。





















评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值