记录一次线上对外接口服务堆区OOM问题的跟踪

第一次问题:kubernetes pod频繁重启 容器内存占用不断升高 达到10g就自动重新构建

jvm参数设置:
-Xms4g -Xmx10g -XX:ParallelGCThreads=3 -XX:+UseParNewGC
开始就怀疑是OOM问题导致服务崩溃,想看日志有没有打印OOM异常信息,可是每次重启都把原来映射到持久卷的日志文件覆盖(在这里吐槽一下同事,为什么日志不分日期,为什么每次重启容器日志都会被覆盖)
所以加了两个参数:
OOM时输出dumap文件:-XX:+HeapDumpOnOutOfMemoryError -XX:HeapDumpPath=/logs/dump
打印gc日志:-XX:+PrintGCDetails -Xloggc:/logs/gc.log
打算下次重启之后查看分析dumap文件和gc日志
…可结果令人大失所望,程序并没有发生OOM异常。问同事kubernetes并没有开启健康检查,然后检查容器配置配置参数,发现了问题:容器最大内存 10g,,java进程堆最大内存也是10g…(无力吐槽)
立马把容器内存加大之后重启服务打算着手优化 full gc 如此频繁的问题

OOM问题导致系统崩溃

那么真正的问题来了,上线一段时间后客户反映说接口没有响应了,看日志接口响应时间也非常慢,因为没有开启健康检查,服务并没有自动重启,java进程也没有被清理,查看日志确实发生了内存溢出,分析dumap文件发现大量的 org.apache.commons.net.ftp.FTPFile 对象和 java.util.GregorianCalendar占用了很大的内存 查看gcroots FTPFile 对象几乎都是在一个FTPFile数组中,,GregorianCalendar 对象都是在FTPfile中的一个成员变量引用
跟踪代码后发现了一段很可疑的代码:

            ftpClient.changeWorkingDirectory(remotePath);//转移到FTP服务器目录
            ftpClient.enterLocalPassiveMode();
            FTPFile[] fs = ftpClient.listFiles();
            for(FTPFile ff:fs){
                if(ff.getName().equals(fileName)){
                    File localFile = new File(localPath+"/"+ff.getName());
                    OutputStream is = new FileOutputStream(localFile);
                    ftpClient.retrieveFile(ff.getName(), is);
                    is.close();
                }
            }

这是一段从ftp文件服务器上下载文件的代码
登录ftp文件服务器之后彻底懵逼:下载文件的那个文件夹中有多达60多w的图片 而且数量时刻在增加
也就是说每一个客户请求都在加载一个60多万长度FTPfile数组,然后去遍历,,,难怪响应会慢,难怪fullgc 会如此频繁,甚至发生OOM

然后剩下的就把代码贴给开发负责人修改了 =.= =.= =.=

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值