Netty ByteBuf泄露定位修改。
1. ByteBuf
2. 问题描述
日志记录中报堆外内存溢出。
3. 问题定位及修改
Netty提供了ByteBuf泄露的检测机制。
JVM启动参数中添加: -Dio.netty.leakDetectionLevel=advanced , log4j2.xml配置io.netty日志记录即可。
- 禁用(DISABLED) – 完全禁止泄露检测,省点消耗。
- 简单(SIMPLE) – 默认等级,告诉我们取样的1%的ByteBuf是否发生了泄露,但总共一次只打印一次,看不到就没有了。
- 高级(ADVANCED) – 告诉我们取样的1%的ByteBuf发生泄露的地方。每种类型的泄漏(创建的地方与访问路径一致)只打印一次。对性能有影响。
- 偏执(PARANOID) – 跟高级选项类似,但此选项检测所有ByteBuf,而不仅仅是取样的那1%。对性能有绝大的影响。
检测到如下泄露点,
举例1:
- 13:29:25.273 [MODBUS_MESSAGE_POOL-thread-14] [] [] [] ERROR io.netty.util.ResourceLeakDetector - LEAK: ByteBuf.release() was not called before it's garbage-collected. See http://netty.io/wiki/reference-counted-objects.html for more information.
- Created at:
- io.netty.buffer.AdvancedLeakAwareByteBuf.writeBytes(AdvancedLeakAwareByteBuf.java:604)
- io.netty.buffer.AbstractByteBuf.readBytes(AbstractByteBuf.java:849)
- com.pinnet.protocol.hwmodbus.message.ModbusMessageRunnable.run(ModbusMessageRunnable.java:46)
- java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1149)
- java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:624)
- java.lang.Thread.run(Thread.java:748)
可以看到readBytes()创建后,没有释放。
修改:
- buffer.readBytes(4).release();
举例2:
- 2018-06-30 13:29:25.278 [MESSAGE_POOL-thread-14] [] [] [] ERROR io.netty.util.ResourceLeakDetector - LEAK: ByteBuf.release() was not called before it's garbage-collected. See http://netty.io/wiki/reference-counted-objects.html for more information.
- #1:
- io.netty.handler.codec.ByteToMessageDecoder.channelRead(ByteToMessageDecoder.java:273)
- io.netty.channel.AbstractChannelHandlerContext.invokeChannelRead(AbstractChannelHandlerContext.java:362)
- io.netty.channel.AbstractChannelHandlerContext.invokeChannelRead(AbstractChannelHandlerContext.java:348)
- io.netty.channel.AbstractChannelHandlerContext.fireChannelRead(AbstractChannelHandlerContext.java:340)
- io.netty.handler.timeout.IdleStateHandler.channelRead(IdleStateHandler.java:286)
- io.netty.channel.AbstractChannelHandlerContext.invokeChannelRead(AbstractChannelHandlerContext.java:362)
- io.netty.channel.AbstractChannelHandlerContext.invokeChannelRead(AbstractChannelHandlerContext.java:348)
- io.netty.channel.AbstractChannelHandlerContext.fireChannelRead(AbstractChannelHandlerContext.java:340)
- io.netty.handler.ssl.SslHandler.unwrap(SslHandler.java:1380)
- io.netty.handler.ssl.SslHandler.decodeJdkCompatible(SslHandler.java:1159)
- io.netty.handler.ssl.SslHandler.decode(SslHandler.java:1194)
- io.netty.handler.codec.ByteToMessageDecoder.decodeRemovalReentryProtection(ByteToMessageDecoder.java:489)
- #2:
- io.netty.buffer.AdvancedLeakAwareByteBuf.getUnsignedShort(AdvancedLeakAwareByteBuf.java:172)
- io.netty.handler.codec.LengthFieldBasedFrameDecoder.getUnadjustedFrameLength(LengthFieldBasedFrameDecoder.java:469)
- io.netty.handler.codec.LengthFieldBasedFrameDecoder.decode(LengthFieldBasedFrameDecoder.java:417)
- com.pinnet.protocol.hwmodbus.tcp.MobusLengthDecoder.decode(MobusLengthDecoder.java:32)
- #3:
- io.netty.buffer.AdvancedLeakAwareByteBuf.order(AdvancedLeakAwareByteBuf.java:70)
- io.netty.handler.codec.LengthFieldBasedFrameDecoder.getUnadjustedFrameLength(LengthFieldBasedFrameDecoder.java:462)
- io.netty.handler.codec.LengthFieldBasedFrameDecoder.decode(LengthFieldBasedFrameDecoder.java:417)
- com.pinnet.protocol.hwmodbus.tcp.MobusLengthDecoder.decode(MobusLengthDecoder.java:32)
- io.netty.handler.codec.LengthFieldBasedFrameDecoder.decode(LengthFieldBasedFrameDecoder.java:343)
- io.netty.handler.codec.ByteToMessageDecoder.decodeRemovalReentryProtection(ByteToMessageDecoder.java:489)
- io.netty.handler.codec.ByteToMessageDecoder.callDecode(ByteToMessageDecoder.java:428)
- io.netty.handler.codec.ByteToMessageDecoder.channelRead(ByteToMessageDecoder.java:265)
- #4:
- Hint: 'decoder' will handle the message from this point.
- #5:
- Hint: 'idleHandler' will handle the message from this point.
修改:解码器中释放Bytebuf in
- public class MobusLengthDecoder extends LengthFieldBasedFrameDecoder {
- public MobusLengthDecoder(ByteOrder byteOrder, int maxFrameLength,
- int lengthFieldOffset, int lengthFieldLength, int lengthAdjustment,
- int initialBytesToStrip, boolean failFast) {
- super(byteOrder, maxFrameLength, lengthFieldOffset, lengthFieldLength,
- lengthAdjustment, initialBytesToStrip, failFast);
- }
- @Override
- protected Object decode(ChannelHandlerContext ctx,
- io.netty.buffer.ByteBuf in) throws Exception {
- ByteBuf buf = (ByteBuf) super.decode(ctx, in);
- // LEAK: ByteBuf.release() was not called before it's garbage-collected.
- in.release();
- ...
- }
- }
Netty ByteBuf泄露定位修改。的更多相关文章
- 对于 Netty ByteBuf 的零拷贝(Zero Copy) 的理解
此文章已同步发布在我的 segmentfault 专栏. 根据 Wiki 对 Zero-copy 的定义: "Zero-copy" describes computer opera ...
- 双11线上压测netty内存泄露
最近线上压测,机器学习模型第一次应用到线上经历双11大促.JSF微服务有报错 LEAK: ByteBuf.release() was not called before it's garbage-co ...
- Netty ByteBuf(图解之 2)| 秒懂
目录 Netty ByteBuf(图解二):API 图解 源码工程 写在前面 ByteBuf 的四个逻辑部分 ByteBuf 的三个指针 ByteBuf 的三组方法 ByteBuf 的引用计数 Byt ...
- IOS免越狱虚拟定位修改工具共享 Jocation
Jocation IOS虚拟定位修改器 具体使用方法可以按照 location cleaned软件相同的操作. 主要是因为本人有一部 IphoneX 和Iphone Xs Max 网上的locatio ...
- netty byteBuf (二)
netty重新定义了byteBuf 而没使用jdk byteBuffer netty byteBuf与jdk byteBuffer的区别 (1)jdk buffer长度固定 byteBuf超过最大 ...
- 从一次netty 内存泄露问题来看netty对POST请求的解析
背景 最近生产环境一个基于 netty 的网关服务频繁 full gc 观察内存占用,并把时间维度拉的比较长,可以看到可用内存有明显的下降趋势 出现这种情况,按往常的经验,多半是内存泄露了 问题定位 ...
- Netty ByteBuf源码分析
Netty的ByteBuf是JDK中ByteBuffer的升级版,提供了NIO buffer和byte数组的抽象视图. ByteBuf的主要类集成关系: (图片来自Netty权威指南,图中有一个画错的 ...
- netty ByteBuf分析
1.Heap Buffer(堆缓冲区) 2.Direct Buffer(直接缓冲区) 3.Composite Buffer(复合缓冲区) 4.PooledByteBuf 池缓冲 readerInex ...
- Netty ByteBuf梳理
我们知道,网络数据的基本单位总是字节.Java NIO提供了ByteBuffer作为它的字节容器,但是这个类使用起来过于复杂,而且也有些繁琐. Netty的ByteBuffer替代品是ByteBuf, ...
随机推荐
- ES6 学习 -- 解构赋值
一.数组解构 **数组解构,解构出来的值跟数组下标是一一对应的,如果左边变量多于右边数组,则左边后面部分变量值为undefined,如果右边数组元素个数多于左边解构变量个数,则左边变量全都有值,且一一 ...
- Docker的概念及基本用法
Docker是PaaS供应商dotCloud开源的一个基于LXC 的高级容器引擎,源代码托管在 GitHub 上, 基于Go语言开发并遵从Apache 2.0协议开源.Docker提供了一种在安全.可 ...
- MySQL基本命令脚本
一.基本命令 1.启动服务 说明:以管理员身份运行cmd 格式:net start 服务名称 示例:net start mysql57 2.停止服务 说明:以管理员身份运行cmd 格式:net sto ...
- scala中Tuple简单使用
/** * Tuple简单使用记录 * 最大22个参数 */ object TupleUse { def main(args: Array[String]): Unit = { // 简单Tuple ...
- VPGAME的Kubernetes迁移实践
VPGAME 是集赛事运营.媒体资讯.大数据分析.玩家社群.游戏周边等为一体的综合电竞服务平台.总部位于中国杭州,在上海和美国西雅图分别设立了电竞大数据研发中心和 AI 研发中心.本文将讲述 VPGA ...
- selenium python bindings 元素定位
1. 辅助 Firepath Firefox是所有做前端的必不可少的浏览器因为firebug的页面元素显示很清晰.用selenium 去定位元素的时候Firefox还有一个非常友好的工具就是firep ...
- android studio 正式版本
注意:以下 Android Studio 下载链接全是 dl.google.com 开头的官方下载,无需tizi,建议用浏览器直接从官方原始链接下载,不要用迅雷下载.不要用迅雷下载.不要用迅雷下载,重 ...
- jquery判断是pc端还是移动端
原文地址:https://www.cnblogs.com/mo-cha/p/6038872.html $(function(){ var system = { win: false, mac: fal ...
- HUD1686-Oulipo-kmp模板题/哈希模板题
The French author Georges Perec (1936–1982) once wrote a book, La disparition, without the letter 'e ...
- 通过JBOSS服务器来实现JMS消息传送
首先必须启动JBOSS服务器,以便于充当JMS传递消息的中间键: JBOSS消息发送端: package test; import java.util.concurrent.CountDownLatc ...