Java架构技术栈Java 杂谈优化及排查

内存泄露排查之线程泄露

2019-04-16  本文已影响1人  若丨寒

基础

内存泄露(Memory Leak)

  1. java中内存都是由jvm管理,垃圾回收由gc负责,所以一般情况下不会出现内存泄露问题,所以容易被大家忽略。
  2. 内存泄漏是指无用对象(不再使用的对象)持续占有内存或无用对象的内存得不到及时释放,从而造成内存空间的浪费称为内存泄漏。内存泄露有时不严重且不易察觉,这样开发者就不知道存在内存泄露,需要自主观察,比较严重的时候,没有内存可以分配,直接oom。
  3. 主要和溢出做区分。

内存泄露现象

perm/metaspace泄露

heap泄露

比较常见的内存泄露

  1. 静态集合类引起内存泄露
  2. 监听器:但往往在释放对象的时候却没有记住去删除这些监听器,从而增加了内存泄漏的机会。
  3. 各种连接,数据库、网络、IO等
  4. 内部类和外部模块等的引用:内部类的引用是比较容易遗忘的一种,而且一旦没释放可能导致一系列的后继类对象没有释放。非静态内部类的对象会隐式强引用其外围对象,所以在内部类未释放时,外围对象也不会被释放,从而造成内存泄漏
  5. 单例模式:不正确使用单例模式是引起内存泄露的一个常见问题,单例对象在被初始化后将在JVM的整个生命周期中存在(以静态变量的方式),如果单例对象持有外部对象的引用,那么这个外部对象将不能被jvm正常回收,导致内存泄露
  6. 其它第三方类

本例(线程泄露)

本例现象

  1. 内存占用率达80%+左右,并且持续上涨,最高点到94%
image
  1. yongGC比较频繁,在内存比较高的时候,伴有FullGC
image
  1. 线程个个数比较多,最高点达到2w+(这个比较重要,可惜是后面才去关注这点)
image
  1. 日志伴有大量异常,主要是三类

刚开始走的错误弯路

  1. 刚开始发现机器内存占用比较多,超过80%+,这个时候思考和内存相关的逻辑
  2. 这个时候并没有去观察线程数量,根据现象 1、2、4,、这个过程没有发现现象3,排查无果后,重新定位问题发现现象3
  3. 由于现象4中的错误日志比较多,加上内存占用高,产生了如下想法(由于本例中很多服务通过mq消费开始)

解决弯路中的疑惑

回归正途的处理逻辑

登录涉事机器

image

httpAsyncClient部分源码

疑问

上一篇 下一篇

猜你喜欢

热点阅读