Netty in Action (十四) 第五章节 第三部分 ByteBufHolder,ByteBuf分配,计数引用

5.4 Interface ByteBufHolder

我们经常在ByteBuf中存储一些正常数据之外,我们有时候还需要增加一些各式各样的属性值,一个Http响应体就是一个很好的例子,除了按照字节传输过来的主体内容,还有状态码,cookie等信息

Netty提供了ByteBufHolder来处理这些常用的用户案例,ByteBufHolder还提供了Netty一些其他的先进特性,例如缓存池,缓存池可以是ByteBuf中直接“借出”获取,如果有需要,“借出”的ByteBuf还可以自动的还到池中

ByteBufHolder提供了一系列的获取底层数据和引用计数的方法,表5.6向你展示了一些常用的方法

如果你想要实现一个消息对象可以在ByteBuf中存储其有效负荷的话,使用ByteBufHolder是一个不错的选择

5.5 ByteBuf allocation

在这个小节中,我们将讨论管理ByteBuf实例的几种方法

5.5.1 On-demand: interface ByteBufAllocator

为了减少分配内存和释放内存的消耗,Netty用接口ByteBufAllocator来实现了管理池,这个池子可以分配我们定义的任何ByteBuf的实例,管理池的使用是应用程序的具体需求,它不会改变ByteBuf的默认的一些API

表5.7向你展示了ByteBufAllocator提供的一些操作

你可以从一个Channel或者从ChannelHandlerContext中获取一个ByteBufAllocator的引用,下面的代码清单说明了这些方法

Netty提供了ByteBufAllocator接口的两种具体的实现,PooledByteBufAllocator和UnpooledByteBufAllocator,前者池化存储ByteBuf来提高性能和减少内存碎片的出现,这种方法使用比较出名的高效的“jemalloc”来分配管理内存,这种技术已经被用在了目前比较流行的操作系统中了,或者没有池化存储ByteBuf的实例,而是每次调用返回一个新的实例

Netty默认是使用PooledByteBufAllocator,但是这可以通过修改ChannelConfig或者通过你在项目中bootstrap时指定特定的不同类型来轻易改变这个默认值,详细的信息可以参考第八章的内容

5.5.2 Unpooled buffers

在某些情况下,你可能没有ByteBufAllocator的引用,在这种情况下,Netty提供了一个特殊的类叫Unppoled,它提供了一个静态的工具方法来创造一个非池化的ByteBuf实例,表5.8展示了Unpooled中比较重要的方法

Unpooled的类也可以使ByteBuf不用于非网络的项目中,使这些项目可以在高性能的可扩展的bufferAPI下获益,并且使用这个不会牵扯到Netty的一些其他的组件

5.5.3 Class ByteBufUtil

ByteBufUtil提供了很多静态的工具方法来管控ByteBuf,因为ByteBufUtil的API是通用的,与池无关的,这些方法可以被除了分配内存的类实现之外,还可以供其他的类使用

在这些静态方法中最最重要的方法可能就是hexdump方法了,这个方法将ByteBuf包含的内容打印成一个十六进制的字符,这在很多情形下显得很是重要,当定位问题和输出日记的时候,十六进制的表示比直接获取byte的值更加友好,还有就是,十六进制版本的数据可以很轻易地转回真实的数据格式

另一个有用的方法就是equals的方法了,这个方法可以确认两个ByteBuf的实例是否相等,如果你实现了你自己的ByteBuf的类的话,你可能会发现ByteBufUtil其他的一些比较有用的方法

5.6 Reference counting

引用计数是一门优化内存使用的技术,如果一个对象所持有的资源不再被任何对象引用的时候,将会释放这部分的资源,Netty在其第四版本为ByteBuf和ByteBufHolder引入了引用计数这项技术,ByteBuf和ByteBufHolder都实现了ReferenceCounted技术

关于引用计数的技术的理论并不是很复杂,大部分情况下它会追踪一个具体对象被引用的个数,一个实现ReferenceCounted接口的实例一般对一个存活的对象开始计数为1,只要对该对象的引用的个数不是0的情况下,这个对象所持有的资源肯定不会被释放,当一个存活的对象引用的个数降至0,那么这个实例将会被释放,注意,关于"释放"的明确定义其实并不是很明确,但是至少如果一个对象已经被"释放",那么这个对象将不再能够被使用

引用计数对于池技术的实现是至关重要的,例如PooledByteBufAllocator,这个可以减少内存分配的损耗,在下面的两个代码清单中展示了这个例子

如果尝试获取一个引用计数的具体对象,但是该对象已经被释放的时候,会抛出一个IllegalReferenceCountException的异常

注意一个对象可以在它自己特有的方法中定义它自己的释放计数的契约,我们可以假设一下它的实现方法release只是设置它的引用计数为0,不管它真实的当前引用计数是多少的时候,这将使这个存活的对象立马无效变得不合法

WHO IS RESPONSIBLE FOR RELEASE?大体上讲,最后一次获取到该对象的负责释放它,在第六章中,我们将讲解它与它相关联的ChannelHandler和ChannelPipeline

5.7 Summary

这个章节致力于学习Netty的数据容器,容器都是基于ByteBuf的,我们一开始解释了ByteBuf的性能为什么比JDK的高,我们也强调了说明了一个个新的API,并解释了它们使用的每一个场景

以下,是我们刚刚提及过的:

1)read和write两个不同的索引控制这我们对数据的操作

2)不同的内存使用方法---backing arrays 和 direct buffers

3)可以使用CompositeByteBuf来使多种ByteBuf聚集

4)数据接入的方法:searching,slicing和copying

5)read,write,get和set这些方法的API

6)ByteBufAllocator池和引用计数

在接下来的一个章节中,我们关注的组件是ChannelHandler,它是我们数据处理逻辑的核心关键,因为ChannelHandler大类使用ByteBuf,你将开始看到Netty的一些核心组件将被整合在一起被使用

时间: 2024-10-08 22:02:44

Netty in Action (十四) 第五章节 第三部分 ByteBufHolder,ByteBuf分配,计数引用的相关文章

中文数字转换成阿拉伯数字(一千二百三十四万五千六百七十八-->12345678)

昨天老大问我又没有写过中文数字转换成阿拉伯数字,我说没有,我说那应该简单啊,就是将中文对应的数字换成阿拉伯数字就好了啊,比如一就换成1,二就换成2…十换成10.可是那么问题来了…… 一十二呢…不能是1102吧…这不就坑爹了吗?一百万呢………所有我苦苦思索,花费了我差不多半天的时间,终于写出了下面的程序. 1 public static void main(String[] args){ 2 3 Map<Character, String> numberMap = new HashMap<

Welcome to Swift (苹果官方Swift文档初译与注解二十四)---163~170页(第三章完--第四章 流程控制)

Mutability of Collections (可变集合) 字典和数组都是在一个集合里储存多个值.如果你创建数组或字典后赋值给一个变量,那么这个集合就是可变的( mutable).这就意味着你在创建这个集合之后,依然可以改变这个集合的 大小,添加元素到集合里或者删除已有的元素.相反地,如果你创建的数组或者字典赋值给一个常量,那么这个集合就是不能修改的,也就是说字典或者数组是不可变的(immutable) 对于字典,不可变就意味着你不能替换里面已有的键值对,一个不可变的字典在它一创建出来就是

第三百六十四、五、六、七天 how can I 坚持

放假就想偷懒,时间过得真快,三天,加周五四天. 周五,弟弟来北京,下班去北京南站接了他,没出站,出站就六块钱啊.晚上带他到一个餐馆炒了几个菜,真难吃啊,是在餐馆吃的最难吃的菜了,没有之一.. 周六,一起去西单,玩了玩,看了看苹果SE,中午吃的呷哺,带他买了两件衣服,一件短袖T恤-一件白色衬衣.晚上回来又去吃了个烤鱼,挺happy. 昨天,周日,在家休息了一天,中午炒了几个菜,蒸的米饭,中午,徐斌他同事还过来了,买了不少水果,不过,不喜欢吃草莓..下午把弟弟给送走了,给他买了个煎饼.够折腾的,虽然

第四百四十四、五天 how can I 坚持

貌似昨天写的东西没保存上啊,好可悲. 昨天写的啥来,学了下过滤器,还有下班吃烤串. 今天下班学了下监听器,然后就偷懒了,ls.yj让给买阿胶,现在阿胶好贵啊. 心里空拉拉的,hx竟然没有给该备注,也是醉了. 一会看看看草稿箱有我昨天写的东西吗,好失落,明天他们要来我这炖鱼,一块玩玩也挺好. 睡觉.

第二百四十四、五天 how can I 坚持

昨天忘了.不知咋忘的,加班加迷糊了? 昨天联调接口,又加班了,好歹基本调通了. 今天,下午,开会,有点被领导批的意思,不是批我,是批我们团队. 团队. 不懂自己. 这样做有意义嘛. 睡觉.好烦. 到底应该记点啥.乱七八糟的,明天还得改接口. 睡觉了,打电话都不接.

JAVA学习第二十四课(多线程(三))- 线程的同步

继续以卖票为例 一.线程安全问题的解决 同步的第一种表现形式:同步代码块 思路: 将多条操作共享数据的线程代码封装起来,当有线程在执行这些代码的时候,其他线程是不允许参与运算的,必须要当期线程把代码执行完毕后,其他线程才可以参与运算 在java中用同步代码块解决这个问题 同步代码块格式: synchronized(对象) { 需要被同步的代码部分 } class Ticket implements Runnable { private int num = 100; Object god = ne

Scala入门到精通——第二十四节 高级类型 (三)

作者:摆摆少年梦 视频地址:http://blog.csdn.net/wsscy2004/article/details/38440247 本节主要内容 Type Specialization Manifest.TypeTag.ClassTag Scala类型系统总结 在scala中,类(class)与类型(type)是两个不一样的概念.我们知道类是对同一类型数据的抽象,而类型则更详细. 比方定义class List[T] {}, 能够有List[Int] 和 List[String]等详细类型

Python 学习笔记(十四)Python类(三)

完善类的内容 示例: 1 #! /usr/bin/env python 2 # coding =utf-8 3 4 #通常类名首字母大写 5 class Person(object): 6 7 """ 8 This is about a person #类文档 9 """ 10 11 def __init__(self,name,lang="python"):#初始化函数,类被实例化的时候,要执行 12 self.name =

Netty in Action (十二) 第五章节 第一部分 简介ByteBuf

第五章 ByteBuf(分四部分翻译) 本章节包括: 1)ByteBuf------Netty的数据容器 2)API介绍 3)使用案例 4)内存分配 我们之前提到过很多次,网络传输数据的最基本的数据单元是byte,Java的NIO提供了ByteBuffer作为字节的容器,但是这个类的使用有些过于复杂和麻烦 Netty对ByteBuffer提供了一个可选方案ByteBuf,一个很好的解决方案,解决了JDK原生的ByteBuffer的API使用不易的问题,同时ByteBuf为应用程序开发者提供了一系