Netty笔记--ByteBuf释放
参考资料:http://www.maljob.com/pages/newsDetail.html?id=394
参考资料:http://www.blogjava.net/liuguly/archive/2014/05/03/413172.html
1.为什么要有引用计数器
Netty里四种主力的ByteBuf,
其中UnpooledHeapByteBuf 底下的byte[]能够依赖JVM GC自然回收;而UnpooledDirectByteBuf底下是DirectByteBuffer,如Java堆外内存扫盲贴所述,除了等JVM GC,最好也能主动进行回收;而PooledHeapByteBuf 和PooledDirectByteBuf,则必须要主动将用完的byte[]/ByteBuffer放回池里,否则内存就要爆掉。所以,Netty ByteBuf需要在JVM的GC机制之外,有自己的引用计数器和回收过程。
2. 引用计数器常识
计数器基于 AtomicIntegerFieldUpdater,为什么不直接用AtomicInteger?因为ByteBuf对象很多,如果都把int包一层AtomicInteger花销较大,而AtomicIntegerFieldUpdater只需要一个全局的静态变量。
所有ByteBuf的引用计数器初始值为1。
调用release(),将计数器减1,等于零时, deallocate()被调用,各种回收。
调用retain(),将计数器加1,即使ByteBuf在别的地方被人release()了,在本Class没喊cut之前,不要把它释放掉。
由duplicate(), slice()和order(ByteOrder)所创建的ByteBuf,与原对象共享底下的buffer,也共享引用计数器,所以它们经常需要调用retain()来显示自己的存在。
当引用计数器为0,底下的buffer已被回收,即使ByteBuf对象还在,对它的各种访问操作都会抛出异常。
3.谁来负责Release
在C时代,我们喜欢让malloc和free成对出现,而在Netty里,因为Handler链的存在,ByteBuf经常要传递到下一个Hanlder去而不复还,所以规则变成了谁是最后使用者,谁负责释放。
另外,更要注意的是各种异常情况,ByteBuf没有成功传递到下一个Hanlder,还在自己地界里的话,一定要进行释放。
3.1 InBound Message
在AbstractNioByteChannel.NioByteUnsafe.read() 处,配置好的ByteBufAllocator创建相应ByteBuf并调用 pipeline.fireChannelRead(byteBuf) 送入Handler链。
根据上面的谁最后谁负责原则,每一个Handler对消息可能有三种处理方式
对原消息不做处理,调用 ctx.fireChannelRead(msg)把原消息往下传,那不用做什么释放。
将原消息转化为新的消息并调用 ctx.fireChannelRead(newMsg)往下传,那必须把原消息release掉。
如果已经不再调用ctx.fireChannelRead(msg)传递任何消息,那更要把原消息release掉。
假设每一个Handler都把消息往下传,Handler并也不知道谁是启动Netty时所设定的Handler链的最后一员,所以Netty会在Handler链的最末补一个TailHandler,如果此时消息仍然是ReferenceCounted类型就会被release掉。
不过如果我们的业务Hanlder不再把消息往下传了,这个TailHandler就派不上用场。
3.2 OutBound Message
要发送的消息通常由应用所创建,并调用 ctx.writeAndFlush(msg) 进入Handler链。在每一个Handler中的处理类似InBound Message,最后消息会来到HeadHandler,再经过一轮复杂的调用,在flush完成后终将被release掉。
3.3 异常发生时的释放
多层的异常处理机制,有些异常处理的地方不一定准确知道ByteBuf之前释放了没有,可以在释放前加上引用计数大于0的判断避免异常;
有时候不清楚ByteBuf被引用了多少次,但又必须在此进行彻底的释放,可以循环调用reelase()直到返回true。
注意:调用writeAndFlush方法,会将ByteBuf的refCnt置为0,从而释放
Netty笔记--ByteBuf释放的更多相关文章
- 【Netty】Netty之ByteBuf
一.前言 前面已经学习了Netty中传输部分,现在接着学习Netty中的ByteBuf. 二.ByteBuf 2.1 ByteBuf API 在网络上传输的数据形式为Byte,Java NIO提供了B ...
- Netty笔记——技术点汇总
目录 · Linux网络IO模型 · 文件描述符 · 阻塞IO模型 · 非阻塞IO模型 · IO复用模型 · 信号驱动IO模型 · 异步IO模型 · BIO编程 · 伪异步IO编程 · NIO编程 · ...
- java.neo的ByteBuffer与Netty 的ByteBuf
JDK的ByteBuffer的缺点: 1.final byte[] hb;这是JDKde ByteBuffer对象中用于存储数据的对象声明;可以看到,其字节数组是被声明为final的,也就是长度是固定 ...
- Netty中ByteBuf的引用计数线程安全的实现原理
原文链接 Netty中ByteBuf的引用计数线程安全的实现原理 代码仓库地址 ByteBuf 实现了ReferenceCounted 接口,实现了引用计数接口,该接口的retain(int) 方法为 ...
- Netty的ByteBuf
https://blog.csdn.net/thinking_fioa/article/details/80795673 netty的ByteBuf知识点
- netty笔记(一)--Demo
Netty是一个Java开源框架,用于传输数据.由server和client组成,封装了Java nio,支持TCP, UDP等协议.这里写了一Demo EchoClientHandler.java ...
- Netty之ByteBuf
本文内容主要参考<<Netty In Action>>,偏笔记向. 网络编程中,字节缓冲区是一个比较基本的组件.Java NIO提供了ByteBuffer,但是使用过的都知道B ...
- Netty笔记
1 基本介绍 Bootstrap Netty应用程序通过设置 bootstrap(引导)类开始,该类提供了一个用于应用程序网络层配置的容器.Bootstrap有两种类型,一种是用于客户端的Bootst ...
- Netty 笔记
1.Netty 是一款异步的事件驱动的网络应用程序框架,支持快速地开发可维护的高性能的面向协议的服务器和客户端. 2.早期Java API 使用的阻塞函数 // 创建一个新的ServerSocket, ...
随机推荐
- Wow! Such Doge! - HDU 4847 (水题)
题目大意:题目描述了一大堆.....然而并没什么用,其实就是让求给的所有字符串里面有多少个"doge",不区分大小写. 代码如下: ====================== ...
- poj2569
http://poj.org/problem?id=2965 好吧终于没有图片了,这道题看起来应该简单一些吧,毕竟已经有7000多人A了,好吧,还是先看看题目再说. 题目大意: //还是吃过晚饭后再看 ...
- JQuery实现悬浮工具条
实现效果如下 html代码 <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http ...
- cat-mvc 一个nodejs mvc 框架
不多说,自己看,哈哈哈 https://www.npmjs.com/package/cat-mvc
- 使用IndexReader.repen提高搜索速度
1,使用indexreader创建indexsearcher. 2,indexsearcher在使用完了以后不要关闭. 3.使用indexreader.isCurrent()判断索引是否被indexw ...
- SQL Server 2008中增强的"汇总"技巧
本文转载:http://www.cnblogs.com/downmoon/archive/2012/04/06/2433988.html SQL Server 2008中的Pivot和UnPivot: ...
- Meth | 安装Linux Mint 18以后grub2 win10启动引导项丢失??!!
进入mint,打开终端输入:sudo update-grub2
- [转] linux新的API signalfd、timerfd、eventfd使用说明
http://blog.csdn.net/gdutliuyun827/article/details/8460417 三种新的fd加入linux内核的的版本: signalfd:2.6.22 time ...
- Android(java)学习笔记215:多线程断点下载的原理(JavaSE实现)
1. 为什么需要多线程下载? 服务器的资源有限,同时的平均地分配给每个客户端.开启的线程越多抢占的服务的资源就越多,下载的速度就越块. 2. 下载速度的限制条件? (1)你的电脑手机宽带的带宽 ...
- Creating a Background Service ——IntentService
The IntentService class provides a straightforward structure for running an operation on a single ba ...