生产环境内存溢出(OOM)排查

一、背景

1:系统通过MQ接受数据,经过业务处理,调用第三方SDK api

2:系统上线后,线程数达到15K(1w5个线程)

3:报错:java.lang.OutOfMemoryError: unable to create new native thread,内存溢出

二、排查

1:查看tcp状态

1.1:established状态有4k,在系统高峰并发下,这么多建立连接可以理解为正常

1.2:close_wait达到了13k, 说明是服务端(推送sdk服务端)主动断开连接,(为什么是服务端主动断开,正常是client断开连接)

2:通过jstack查看jvm线程堆栈状态统计数

2.1:目前正在wait的线程达到8k

2.2:打印具体详细线程栈

2.3:基本可以确定占用线程数高就是okhttp

三、思考

1:服务端主动断开连接,说明是连接达到了服务端的超时时间,不然不会主动断开 -->

2:使用了okhttp,为什么就会有那么多线程数 -->

3:查看源码,okhttp每次创建socket,默认keepalive(HTTP 2)是5分钟,所以可以理解为5分钟的长连接

4:每一次new一个okHttpClient,会有一个http连接的线程池(为了复用),同时又有一个线程通过死循环回收线程池过期的http连接

5:业务代码每来一次请求,就new一个okHttpClient,在并发高的情况下和默认5分钟的http生命周期,可以导致上面说的大量被动断开连接的状态close_wait(5分钟达到了服务器的timeout时间)

6:new一个okHttpClient,同时会有一个守护线程在死循环回收http连接,可以导致上面说的为什么线程数15k

四、解决

1:使用单例okhttpclient, okhttpclient本身就提供http(socket)请求连接池,目标就是复用连接,避免tcp三次握手和挥手带来的效率问题。

线程数恢复正常

无、总结

1:监控一定要全

2:基础网络知识要会

3:使用jvm排查工具

4:熟悉框架的源码

  • 3
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值