一个比较明显的OOM的排查过程

简介:

淘江湖由于之前遇到过因爬虫导致对用户中心的访问飚高而险些发生问题的情况,所以在其最近的一个项目中升级TDDL到2.4.4版本,以使用tddl的流控功能。但是在一次压测6个小时后产生了OOM异常。用晓锋的TProfiler分析结果是:

num #instances #bytes class name

1: 880137 104619672 char[]
914733 21953592 | +–java.lang.String
774175 37160400 | | +–com.**Profiler$Entry
790764 31074808 | | | +–java.lang.Object[]
781966 18767184 | | | | |–java.util.ArrayList

790764 31074808 | | +–java.lang.Object[]
781966 18767184 | | | +–java.util.ArrayList
774175 37160400 | | | | |–com.**Profiler$Entry

直接用jmap -histo查看结果是:

num #instances #bytes class name

1: 4542494 544227352 [C
2: 4429530 212617440 com.**Profiler$Entry
3: 4451761 165336648 [Ljava.lang.Object;
4: 4577468 109859232 java.lang.String
5: 4439023 106536552 java.util.ArrayList
6: 18058 24432336 [I

初步认为是com.**.Profiler没有release造成的问题,但是业务方的代码只有两行调用了Profiler,
包括其引用的jar包的代码中也没有发现忘记release的地方。
再用Mat分析过dump文件,一个线程引用了490多M的对象,Profiler$Entry本身占了92M的内存,但是占用了480M空间,
因此确定无疑是Profiler没有release造成的,所以写了一个BTrace脚本跟踪Profiler的enter和release调用,结果如下
com.taobao.matrix.center.interceptor.ProfilerInterceptor.invoke(ProfilerInterceptor.java:14) = 1541000 enter
com.alibaba.webx.filter.timer.TimerFilter.doFilter(TimerFilter.java:97) = 1 enter
com.taobao.matrix.center.interceptor.ProfilerInterceptor.invoke(ProfilerInterceptor.java:17) = 1541000 release

询问淘江湖的压测方法,是发了一个http请求后触发服务端开启线程池压测,直到压测完http请求才返回。因此在整个过程中
com..filter..XXFilter.doFilter(XXFilter.java:97) 调用Profiler.enter之后都没有立即释放。
com.**.Profiler使用ThreadLocal保存跟踪信息的,多线程情况下本来也不会有问题,
但碰巧线程池用的reject策略是Caller Run,而其并发量非常大,这样每次caller run时进入的entry都不会释放,直到最后OOM

修改压测代码,让http请求立即返回后服务端再开始压测,问题解决

本文来源于"阿里中间件团队播客",原文发表时间"  2011-03-08"

相关文章
|
测试技术 API
如何用Apifox 发送接口请求?
今天我们就来学习下大部分都要用的API工具的接口测试功能,也是对测试人员来说最实用的功能。
如何用Apifox 发送接口请求?
【IntelliJ IDEA】idea修改文件的file is read-only
【IntelliJ IDEA】idea修改文件的file is read-only
3660 0
|
12月前
|
人工智能 缓存 负载均衡
spring boot-MultipartFile 机制
本文详解了 Spring Boot 中 MultipartFile 的工作机制及大文件上传的解决方案。内容涵盖 MultipartFile 的解析流程、上传配置、Feign 上传大文件的内存问题及基于 RestTemplate 的流式上传实现。同时介绍了服务器端如何直接处理 application/octet-stream 类型的文件流,避免内存溢出问题。适合需要优化文件上传性能的开发者参考。
1313 0
|
11月前
|
Ubuntu Linux Shell
手把手教你安装适用于Linux的Windows子系统——Ubuntu
重启完成,你看看重新打开Ubuntu是不是发生了变化,等待几分钟,系统配置完成,根据提示设置用户名和密码即可
|
机器学习/深度学习 人工智能 自然语言处理
详解人工智能(概念、发展、机遇与挑战)
详解人工智能(概念、发展、机遇与挑战)
|
对象存储
阿里云访问资源:NoSuchKey
阿里云访问资源:NoSuchKey
783 0
|
SQL 人工智能 Java
mybatis-plus配置sql拦截器实现完整sql打印
_shigen_ 博主分享了如何在MyBatis-Plus中打印完整SQL,包括更新和查询操作。默认日志打印的SQL用?代替参数,但通过自定义`SqlInterceptor`可以显示详细信息。代码示例展示了拦截器如何替换?以显示实际参数,并计算执行时间。配置中添加拦截器以启用此功能。文章提到了分页查询时的限制,以及对AI在编程辅助方面的思考。
3428 5
mybatis-plus配置sql拦截器实现完整sql打印
|
Prometheus Kubernetes 监控
Kubernetes(K8S) 监控 Prometheus + Grafana
Kubernetes(K8S) 监控 Prometheus + Grafana
887 2
|
存储 编译器 Swift
Swift笔记:Swift中的扩展语法
Swift笔记:Swift中的扩展语法
572 1