在网络编程中,buffer是用来把应用程序的数据发送到网络上的中转站,它的重要行不言而喻。提到buffer就不能不说零拷贝什么的,buffer的内存管理什么的,在dawn中,基于directbuffer重新实现了一个可以自动扩展的零拷贝buffer。它的原理就是一个内存块的链表,数据都是在尾端添加,从头部移出,或者在中间获取、设置。所有的位置信息都是直接通过计算获取,所以,保证了各种情况的存取效率。在数据增加时,如果当前内存不够,则会扩展一个内存块,写到新block中;如果前面的数据消费掉了,则可以使用compact方法,压缩存储空间,抛弃最前面已经消费掉的数据,并把抛弃掉的内存块放回内存池。这样就以最小的数据移动代价来获取最高的存取效率。
所以,只要你以正确的姿势使用了dawn的buffer,你同时在高效的使用buffer了,dawn的底层尽了最大努力降低数据复制的开销。注意:ScalableDirectBuf的当前实现只能支持intel和amd的cpu,在别的cpu上使用 ,可能会崩溃,不过现实生活中绝大部分的cpu都是intel的,所以,我们基本不用担心。
讲了半天的题外话,让我回到ScalableDirectBuf的使用方法上吧,ScalableBuf的最大容量是无限的,只限制于物理内存,它有几个成员变量我们必须了解:
ri(readindex的缩写),wi(writeindex),limitpos(当前容量)
ri是下一个可读数据的位置
wi是下一个可写位置
limitpos 是当前容量。
他们的大小关系:ri<=wi<=limitpos
ScalableDirectBuf有几类方法:
1.写入类方法,以w开头,比如wint是写入一个整数,wi向前移动4个字节,还有wbyte,wlong,等等,类似。
2.读取类方法,以r开头,如rlong,从buffer中读取一个long,ri向前移动8个字节,如果buffer的可读数据不足8个字节,会抛出IndexOutofBound异常。
3.设置方法,以s开头,比如sshort,从某个偏移开始,设置一个short数据,ri和wi都不移动。
4.获取方法,以g开头,比如gbyte,读取某个位置处的一个字节,ri和wi都不移动。
5.和容量有关的函数,readable,当前buffer中可供消费的数据大小。
6.和buffer回收相关的函数,compact,抛弃已经消费的数据,并把空block放回内存池。 release,抛弃所有数据,把所有block放回内存池。
相关的例子,可以参考单元测试:
https://github.com/zhmt/dawn/blob/master/examples/zhmt/dawn/nio/buffer/ScalableDirectBufTest.java
下一篇文章,我们用一个简单的例子来综合运用我们之前学到知识:我们连接baidu的首页,并打印所获取到所有内容,你会看到这很简单。
版权声明:本文为博主原创文章,未经博主允许不得转载。
原文地址:http://blog.csdn.net/zhmt/article/details/46687721