老师,百忙之中务必解惑,谢谢

来源:3-5 服务端口的绑定

正义柔情永在

2018-10-22

老师:
您好,您的视频讲的非常好,但是我的基础有些差,后续还需要慢慢反复学习.我现在工作中有一个项目就是使用netty做的.
已经部署上线了,通过设置-Dio.netty.leakDetectionLevel=ADVANCED 运行了一段时间没有发现LEAK netty内存泄露的字样.
但是自己对netty的理解还是非常有限,希望您能解答如下问题.这些问题也困惑好久了.不胜感谢啊.

1:
netty 中的 缓冲区一共有四种
问题: 池化的缓冲区是否都是在finally 中使用 ReferenceCountUtil.release(buffer) 进行内存回收.还是说ChannelHandler调用链的最后会自动回收?

2: SimpleChannelInboundHandler 中创建的缓冲区是不是都不需要手动回收?
包括 Unpooled.buffer(),Unpooled.directBuffer(),ctx.alloc().buffer(),ch.alloc().directBuffer()

3: 创建的没有池化的缓冲区(Unpooled.xxx)是不是都需要手动回收?通过什么方式回收?也是ReferenceCountUtil.release(buffer)吗?

以上3个问题,就是说,什么情况下,申请的不同的buf 都需要回收,什么情况下,申请的不同的buf是不需要回收的.

4: netty线程模型中一般为主从线程模型,分别为 boss 和 io
boss线程组负责监听端口,接收连接请求,身份认证等.io线程组主要处理网络IO事件.
那么如果在只监听一个端口,不进行身份认证的情况下是否boss线程组的数量就只有一个会被用到,其他的都没有用到?

5:attr(),childattr() 这两个方法分别表示什么?在实战中到底有什么用?什么场景下使用?

6:服务端启动是的handler(非childhandler) 中的channelRead()方法有什么作用?

7: 我的理解pipline 是和channel 绑定的,也就不存在线程不安全的情况(每个channel都是单独的pipline实例).
那么如果我是自定义的序列化协议的情况下.是否可以通过定义
一个成员变量(ByteBuf) 将本地读取到的buf缓存再来,等到多次调用decode方法获取到一个整包后,将成员变量
清空.还是每次decode的时候发觉不是一个完整的包的情况下resetReaderIndex()等到下次读取?
这两种方式是否都是可行的?

8: 接上一个问题.如果是定义灯源byteBuf,那么这个buf定义成直接缓冲区好点,还是堆缓冲区好点.还是在第一次decode方法被调用的时候通过ctx.alloc()进行分配.
if(this.buf ==null){
this.buf = ctx.alloc();
}

写回答

1回答

闪电侠

2018-10-23

1:
netty 中的 缓冲区一共有四种
问题: 池化的缓冲区是否都是在finally 中使用 ReferenceCountUtil.release(buffer) 进行内存回收.还是说ChannelHandler调用链的最后会自动回收?

需要手动回收


2: SimpleChannelInboundHandler 中创建的缓冲区是不是都不需要手动回收?
包括 Unpooled.buffer(),Unpooled.directBuffer(),ctx.alloc().buffer(),ch.alloc().directBuffer()

任何情况下,自己申请的内存都需要自己回收


3: 创建的没有池化的缓冲区(Unpooled.xxx)是不是都需要手动回收?通过什么方式回收?也是ReferenceCountUtil.release(buffer)吗?

对的

以上3个问题,就是说,什么情况下,申请的不同的buf 都需要回收,什么情况下,申请的不同的buf是不需要回收的.

4: netty线程模型中一般为主从线程模型,分别为 boss 和 io
boss线程组负责监听端口,接收连接请求,身份认证等.io线程组主要处理网络IO事件.
那么如果在只监听一个端口,不进行身份认证的情况下是否boss线程组的数量就只有一个会被用到,其他的都没有用到?

对的,默认是线程是懒启动的,只监听一个端口,其他线程是不会启动的,只有用到了才会启动


5:attr(),childattr() 这两个方法分别表示什么?在实战中到底有什么用?什么场景下使用?

给连接绑定上属性,比如 IM 聊天的时候,就可以将session信息绑定在channel上,具体可以参考 https://juejin.im/book/5b4bc28bf265da0f60130116


6:服务端启动是的handler(非childhandler) 中的channelRead()方法有什么作用?
一般用不着,可以忽略


7: 我的理解pipline 是和channel 绑定的,也就不存在线程不安全的情况(每个channel都是单独的pipline实例).
那么如果我是自定义的序列化协议的情况下.是否可以通过定义
一个成员变量(ByteBuf) 将本地读取到的buf缓存再来,等到多次调用decode方法获取到一个整包后,将成员变量
清空.还是每次decode的时候发觉不是一个完整的包的情况下resetReaderIndex()等到下次读取?
这两种方式是否都是可行的?

对的,这个就是netty自定义拆包器的原理

8: 接上一个问题.如果是定义灯源byteBuf,那么这个buf定义成直接缓冲区好点,还是堆缓冲区好点.还是在第一次decode方法被调用的时候通过ctx.alloc()进行分配.
if(this.buf ==null){
this.buf = ctx.alloc();
}
堆外内存

3
0

Java读源码之Netty深入剖析

解析netty各大组件细节,百万级性能调优,设计模式实际运用

2334 学习 · 283 问题

查看课程