雨翔河
首页
列表
关于
循环调用导致的 OOM 问题分析解决
2019-11-27 08:15
> 问题背景: 2019-11-26 14:30左右我们的对外的web应用出现RPC调用超时的异常告警,查了日志下是调用内部广告系统超时,马上联系运维的同事去跟踪排查,因为不是自己项目组的东西,很多是没有权限干涉的。 好在对接口的调用超时有做异常检查,并不会对用户产生影响,但是线程积压的情况是会有的,问题不大。 现在问题是他组同事排查了一天没有找到原因,这就很尴尬了,我们的权限又不足以去查看别人的应用和代码,干着急,只能曲线救国。 在没有代码查看权限和机器权限的情况下要处理这种问题还是有点尴尬的,首先找到该应用的监控发现GC是有异常的。 ![](https://cdn.yuxianghe.net/image/blog/68-1.png) ![](https://cdn.yuxianghe.net/image/blog/68-2.png) 并不是一个节点是这种情况,每个节点都有可能出现,而且是无规律的,断断续续的FullGC,每一次的时间很长。 初步判断是内存泄漏。 找运维聊了下那个应用的JVM配置,之前该应用是4G的内存分配,由于量的增加,4G已经不够,后来增长到了8G,现在是8G的内存也不够,应用重启不久后就会发生GC导致STW。 这下更加可以确定是内存泄漏,找到运维,将堆栈文件hprof导了出来,尴尬的问题来了,我们的开发机器是windows,内存只有16G,导出来的hprof文件是11G,开发本地的机器使用jmc和mat都无法打开进行分析,会直接打爆本地机器。。。 只能让运维去找了台CPU和内存配置都非常高的独立的linux机器来进行分析,将文件导入到服务器,下载好mat,将内存设置到32G再执行命令。 ``` ./ParseHeapDump.sh ./ad.hprof org.eclipse.mat.api:suspects ``` 用了一小会儿结果出来了,让运维把执行结果产生的 `ad_Leak_Suspects` 文件目录压缩后拖到本地机器。 打开一看,真相大白: ![](https://cdn.yuxianghe.net/image/blog/68-3.png) ![](https://cdn.yuxianghe.net/image/blog/68-4.png) 很明显 com.xxx.ad.service.order.impl.OrderCommonServiceImpl.getPointPostScheduleByDate(Ljava/lang/String;)Ljava/util/Map; (OrderCommonServiceImpl.java:xxx) 这段代码存在内存泄漏,因为没有源码,所以只能猜测和分析,从堆栈来看,应该是这个应用有一个RPC的接口被调用的时候,内部的实现使用了stream的流式写法,这个时候得到的应该是一个超级大的容器对象, 函数式的写法里面有一个循环操作,对每一个对象进行了一个处理,处理的逻辑最后还进行了redis的操作。 分析到了这里也只能把问题提交到对应了开发人员了,毕竟没有源码和应用权限,没法去代码层去处理这个问题。 但是通过这里可以看出循环操作一定要小心,大对象的循环操作调用是很可怕的,这种问题已经看到不是第一次了,当然可以肯定的是,这不会是最后一次。
类型:工作
标签:oom,java
Copyright © 雨翔河
我与我周旋久
独孤影
开源实验室