导致Netty内存泄漏的原因很多,例如,使用内存池方式创建的对象忘记释放,或者系统处理压力过大导致发送队列积压。
尽管Netty 采用了NIO非阻塞通信,I/O处理往往不会成为业务瓶颈,但是如果客户端并发压力过大,超过了服务端的处理能力,又没有流控保护,则很容易发生内存泄漏。
【客户端发送大量数据】
问题代码:某个客户端建立多个线程循环发送消息,客户端的发送队列会比较繁忙,此时客户端内存使用会不断飙升。
 
统计GC数据,发现老年代已满,发生多次Full GC,耗时3分钟多,系统已经无法正常运行,如图5-2所示。查看CPU的使用情况,发现GC线程占用了大量的CPU资源,
分析原因查看dump图可以知道NioEventLoop,即消息处理handler线程内存溢出了,继续对引用关系进行分析,发现真正泄漏的对象是 WriteAndFlushTask,它包含了待
发送的客户端请求消息msg 及 promise对象,引用关系示例如图5-5所示。
Netty的消息发送队列为什么会积压呢?通过源码分析发现,调用Channel的write方法时,如果发送方为业务线程,则将发送操作封装成WriteTask,放到Netty的NioEventLoop中执行,源码如下(AbstractChannelHandlerContext):
这里有个结论,如果是业务方线程调用write方法,会被netty强制转化成使用NioEventLoop线程去执行,这里也符合netty的反应器模式设计:链接建立由Reactor线程池处理,接收到的消息转发给handler线程池处理,自然handler也必须负责消息的出栈。
为防止客户端发送巨量消息导致发送队列堆积,则在发送前需要判断该channel能否可读,netty提供了高低水位来实现客户端消息流控,先用setWriteBufferHignWaterMark预设最高字节数,当达到这个高水位时channel会自动变为不可写,改动如下:
在实际项目中,根据业务QPS规划、客户端处理性能、网络带宽、链路数、消息平均码流大小等综合因素计算并设置高水位(WriteBufferHighWaterMark)值,利用高水位做消息发送速度的流控,既可以保护自身,同时又能减轻服务端的压力,防止服务端被压挂。
【什么情况会造成消息挤压发送不出去或发送不及时】
1.网络瓶颈,当发送速度超过网络链接处理能力,会导致发送队列积压。
2.当对端读取速度小于己方发送速度,导致自身TCP发送缓冲区满,频繁发生write0字节时,待发送消息会在Netty发送队列中排队。发送队列堆积的本质是服务端接收不及时,因为消息是从客户端send区转移到服务端recv区的,如果服务端recv区满了则客户端的send区也会逐渐变满,然后客户端数据不能放进send区则只能堆积到队列中。同样的,客户端接收消息不及时业务挤压服务端发送队列。这个情况很好模拟,在服务端程序cahnnelRead方法中设置断点,相当于不接收客户端消息,客户端就很容易出现这个情况。

发送队列积压导致内存泄漏相关推荐

  1. nstimer循环引用_解决NSTimer循环引用导致内存泄漏的六种方法

    demo放在了GitHub 内存泄漏的原因: self强引用timer.timer添加在runloop上,只要timer不销毁self就销毁不了.当然了你可以选择在viewWillDisappear中 ...

  2. 会不会导致内存泄漏_可能会导致.NET内存泄露的8种行为

    原文连接:https://michaelscodingspot.com/ways-to-cause-memory-leaks-in-dotnet/ 作者 Michael Shpilt.授权翻译,转载请 ...

  3. android 栏目编辑,android – 编辑文本导致内存泄漏

    介绍: 我有一个应用程序具有以下结构: ActionBar顶部(ActionBarSherlock) ViewPagerIndicator下面(对于选项卡) ViewPager(主机片段) 我有一个问 ...

  4. 使用智能指针错误导致内存泄漏_C++智能指针使用的那些事

    指针指针的由来 在C/C++里面,内存管理由开发者自己管理.指针变量总是指向一片内存空间,这片内存空间可以是局部变量.也可以是通过malloc.new申请的.如果申请的内存没有释放,就会导致内存泄漏. ...

  5. fastjson带泛型序列化导致内存泄漏

    fastjson带泛型序列化导致内存泄漏 一.背景 某日早上,生产环境告警群出现了大量响应时间在1s多的慢接口,在应用日志中也能找到不少接口超时熔断(响应时间>=5s). 当中有不少接口的SQL ...

  6. C#之异步导致内存泄漏

    C#4.5的新特性,异步处理,同步的编码方式,大大的提高了编程效率.但是今天却由于异步的使用,导致了一个非常严重的内存泄漏. 崩溃截图: 由于本程序是用纯C#开发,不存在非托管内存,而且没有使用静态变 ...

  7. PerfView专题 (第十篇):洞察 C# 终结队列引发的内存泄漏

    一:背景 C# 程序内存泄漏的诱发因素有很多,但从顶层原理上来说,就是该销毁的 用户根 对象没有被销毁,从而导致内存中意料之外的对象无限堆积,导致内存暴涨,最终崩溃,这其中的一个用户根就是 终结器队列 ...

  8. s5 android5.0内存泄漏,android-最初从位图泄漏了未引用的byte [],但被回收的()导致内存泄漏(直到活动停止)...

    我的位图内存泄漏导致内存不足.我在Android 5.0(Samsung S5)上运行了测试.我已经使用Android Studio(1.5.1 2.0.0预览版7)调查了此问题. HPROF内存转储 ...

  9. 动态内存分配导致内存泄漏之处

    摘要:举了几个动态内存分配过程中,发生内存泄漏的例子 1. 分配了内存,却没有及时删除,导致泄漏 1: void doSomething() 2: { 3: int *pnValue = new in ...

最新文章

  1. 返回指针值的函数(1)
  2. 过河 2005年NOIP全国联赛提高组(离散化+dp)
  3. 任务栏网速监控工具NetSpeedMonitor
  4. hadoop免密钥配置
  5. java递归api_javaAPI_IO流基础_递归使用
  6. 感知器 机器学习_机器学习感知器实现
  7. hibernateTemplate 的find 查找方法
  8. 年薪30W的软件测试“老司机”工作经验
  9. 关于c# 静态构造函数的说明
  10. es分页方式search_after
  11. java--javassist学习
  12. ZEMAX知识点:坐标间断面(coordinate break)
  13. 风格迁移-风格损失函数(Gram矩阵)理解
  14. 王爽 《汇编语言》之寄存器
  15. linux之getopt 函数
  16. 如何用技术手段将图片背景变为透明?
  17. Python画各种有趣的图及源码
  18. TeKtronix TDS210数字示波器使用简介
  19. modbus rtu与计算机通讯,Modbus通讯协议原来是这么回事!看完秒懂了
  20. HTML、CSS综合04——浮动、定位、选择器

热门文章

  1. STM32的指令周期
  2. 基于android的lbs技术,基于android的lbs定位系统的设计-电子与通信工程专业论文.docx...
  3. 计算机的应用发展趋势,计算机软件的应用及发展趋势
  4. php视频压缩技术,PHP 实现文件压缩解压操作的方法
  5. 【图论】【网络流】最小割模型
  6. 【每个人都是梵高】A Neural Algorithm of Artistic Style
  7. 2021年全球及中国晶圆代工行业:预计2026年中国大陆晶圆代工全球市场份额将提升至8.8% [图]
  8. 无法删除文件.dll访问被拒绝
  9. 每一趟安心出行的背后,都有哪些黑科技?
  10. android usb 开发:如何跳过usb权限询问,解决绕过android下apk使用usb设备权限查询相应问题,自动获取usb权限...