java httpclient 内存不释放_内存泄露排查之线程泄露

本文分析了一起由于Java HttpClient使用不当导致的内存泄漏问题,特别是线程泄露,表现为内存占用率持续上升,触发频繁GC。问题源于每次新建HttpClient实例并在结束时调用shutdown方法失效,导致线程池中的线程无法正常关闭。解决方案包括改为单例模式以限制线程池大小,以及深入理解HttpClient的关闭机制以避免阻塞。
摘要由CSDN通过智能技术生成

基础

内存泄露(Memory Leak)

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

内存泄露现象

  • heap或者perm/metaspace区不断增长, 没有下降趋势, 最后不断触发FullGC, 甚至crash.
  • 如果低频应用,可能不易发现,但是最终情况还是和上述描述一致,内存一致增长

perm/metaspace泄露

  • 这里存放class,method相关对象,以及运行时常量对象. 如果一个应用加载了大量的class, 那么Perm区存储的信息一般会比较大.另外大量的intern String对象也会导致该区不断增长。
  • 比较常见的一个是Groovy动态编译class造成泄露。这里就不展开了

heap泄露

比较常见的内存泄露

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

本例(线程泄露)

本例现象

  1. 内存占用率达80%+左右,并且持续上涨,最高点到94%

d75d154f354e79fc38751804b30a54c1.png
  1. yongGC比较频繁,在内存比较高的时候,伴有FullGC

cd0b9535c90266b0766ba3e8ac3385e7.png
  1. 线程个个数比较多,最高点达到2w+(这个比较重要,可惜是后面才去关注这点)

d841436b8ce1510e95dc27a4a9b05ad6.png
  1. 日志伴有大量异常,主要是三类
  • fastJosn error

181aeca29eb2d87f38daacf391b2b9ad.png
  • 调用翻译接口识别语种服务错误

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值