java io深入浅出Netty源码剖析程序员

Netty源码(一):Netty中的Buffer

2017-03-22  本文已影响537人  程序员历小冰

最近我学习了NIO相关的知识,然后发现了Netty这个基于NIO的网络应用框架,于是就研究起Netty框架源码,来好好体会一下网络框架的设计理念和思想.
 这个系列的文章不仅会总结Netty各个模块的源码原理,也会写出一些自己对这些设计的理解和体会.
 我基本按照并发编程网上这个系列文章的顺序来进行系列文章的顺序,不同的是我是基于Netty4.1的源码进行分析和讲解.
 为了节约你的时间,本篇文章主要内容如下:

Buffer

Java NIO中的Buffer用于和NIO通道进行交互,数据可以从通道读入缓冲区,也可以从缓冲区写入到通道中.所以说,Buffer其实就是一块可以读写数据的内存,我们将其包装为一个Java对象来提供一系列读写操作.
 Netty并没有直接使用Java NIO的Buffer实现,而是自己实现了一套Buffer框架来满足自己的业务或者性能需求.

ByteBuf的基本原理

读写指针的作用

不同于NIO Buffer的读写指针共用原理,ByteBuf拥有readerIndex,writerIndex两个指针.下面我们就来详细的讲解一下ByteBuf的内部原理.

     +-------------------+------------------+------------------+
     | discardable bytes |  readable bytes  |  writable bytes  |
     |                   |     (CONTENT)    |                  |
     +-------------------+------------------+------------------+
     |                   |                  |                  |
     0      <=      readerIndex   <=   writerIndex    <=    capacity

从示意图中我们可以看出readerIndexwriterIndex最多可以将整个内容空间划分为三块:废弃区,可读区可写区.下面我们就来看一下不同操作下的两个指针的变化.

       +---------------------------------------------------------+
       |             writable bytes (got more space)             |
       +---------------------------------------------------------+
       |                                                         |
 readerIndex(0)
  writerIndex(0)                   <=                   capacity
       +-------------------+------------------+------------------+
       |  readable bytes  |  writable bytes                      |
       |     (CONTENT)    |                                      |
       +--------- --------+------------------+------------------
       |                  |                                      |
     readerIndex(0) <= writerIndex(10)           <=        capacity

 +-------------------+------------------+------------------+
 | discardable bytes |  readable bytes  |  writable bytes  |
 |                   |     (CONTENT)    |                  |
 +-------------------+------------------+------------------+
 |                   |                  |                  |
 0      <=      readerIndex(5)   <=   writerIndex(10)    <=  capacity
       +------------------+--------------------------------------+
       |  readable bytes  |    writable bytes (got more space)   |
       +------------------+--------------------------------------+
       |                  |                                      |
  readerIndex (0) <= writerIndex (5)              <=        capacity

零拷贝

OS层次上Zero-copy,就是在操作数据时,不需要将数据buffer从一个内存区域拷贝到另一个内存区域,因为减少了一次内存的拷贝,因此CPU的效率得到了提升.
Nettyzero-copy体现在很多方面.比如Buffer的compose,duplicate,slice操作时不会拷贝底层的数据.而是通过ByteBuf对象的组合来实现上述的操作

Pool和Reference Count

4.0之后的版本实现了高性能的Buffer池,分配策略则是结合了buddy allocation和slab allocation的jemalloc变种,实现类为PoolArena,这样的话,可以在频繁分配和释放Buffer时缓解GC压力,还可以在初始化新buffer时减少内存带宽消耗(初始化时不可避免的要给buffer数组赋初始值).
ByteBuf引入了Reference Count机制,你需要在不适用它的时候调用ReferenceCountUtil.release方法来减少它的引用.

后记

 感觉自己在研究或在阅读源代码时还是有些问题,起始ByteBuf并不是Netty的关键所在,不应该花费这么长时间.以后还是要带着目的来看源码,不能把时间浪费在一些代码细节上.

引用

上一篇 下一篇

猜你喜欢

热点阅读