Future & Promise
jdk的future只能同步
netty的future可以同步也能异步,但都是等到任务结束才能得到结果
netty promise脱离了任务独立存在,只作为两个线程传递结果的容器
channel
用来处理Channel的各种事件,分为入站和出站
pipeline
所有的handle连成串,就是pipeline
pipeline.addlast():添加处理器
super.channelRead():把数据传递给下一个handle
使用channel.write()会从tail开始往前找,使用ctx会从当前的handle开始往前找
ByteBuf
是对字节数据的封装
创建方法:
ByteBuf buffer = ByteBufAllocator.DEFAULT.buffer(10);
直接内存和堆内存
直接内存创建和销毁代价昂贵,但读写性能高(少一次内存复制),适合配合池化功能一起使用
直接内存对GC压力小,因为这部分内存不受JVM垃圾回收的管理,但也要及时主动释放
池化
池化最大的意义在于可以重用bytebuf,如果没有池化,每次都要创建新的bytebuf实例,这个操作对于直接内存代价昂贵,有了池化可以重用bytebuf池中的实例,并且采用内存分配算法提升分配效率,高并发时,池化也更节约内存,防止内存溢出
组成
转存失败重新上传取消
bytebuf有容量和最大容量,容量超了就会开启扩容。
其中灰色为读指针已经读过的地方,为废弃的,绿色为写指针已经写了,读指针还没读的区域,为可读区域,蓝色部分为容量足够但写指针还没写的区域,为可写区域
内存释放
Netty使用的是引用计数法来控制回收内存,每个bytebuf对象的初始计数为1,调用release方计数减1,如果计数为0,则被回收,调用retain方法计数加一
由谁来执行release呢?
谁是最后负责人,谁来执行release。
slice
零拷贝的体现之一,对bytebuf进行切片成多个Bytebuf,切片后的bytebuf没有发生内存复制,切片后的bytebuf维护独立的read,write指针
优势
-
池化,可以复用池中bytebuf实例,更节约内存,减少内存溢出的可能
-
读写指针分离,不需要像bytebuffer一样切换读写模式
-
可以自动扩容
-
支持链式调用
-
很多地方体现了零拷贝,例如slice,duplicate,compositebytebuf