網状(6個)のバッファソースコード解析

問題:

  • ByteBuffと伝統的なByteBuffの差ネッティーは何ですか?
  • HeapByteBufとDirectByteBuf違いは?HeapByteBuf:原因をコピーする必要があるため、ヒープ・メモリ、短所、ソケットの送信時間を利用して、ゆっくりとDirectByteBuf:外部メモリヒープは、ゼロコピーを使用することができます

アウトライン

netty ByteBuf 存在两个指针,分成三个区域: 已读区(可丢弃),未读区(未读),可写区 。不像之前JDK 的 ByteBuffer 中只有一个position 指针。例如以下示例 : 
    パブリック静的無効メイン(文字列[] args){
        ByteBufferのバッファ= ByteBuffer.allocate(88)。
        文字列値=「ネッティー~~」。
        buffer.put(value.getBytes())。
        //このフリップ()メソッドは、呼び出されていない場合、誤った場所を読まれることに注意してください
        buffer.flip();
        バイト[] VARRAY =新しいバイト[buffer.remaining()]。
        BUFFER.GET(VARRAY)。
        文字列結果=新しい文字列(VARRAY)。
        System.out.println(結果)。
    }

概述一下netty ByteBuff 的特点 : 
  • APIが豊富で、かつ存在readIndex writeIndex二つのポインタ、読み、書きやすいです
  • 動的な拡張
  • この方法は、互換性のあるJDKのByteBufferを提供します

分類

内存池,循环利用创建的 ByteBuf 对象提升内存使用效率,降低由于高负载导致的频繁 GC . 
PooledByteBuf 抽象类的子类 : 
  • PooledDirectByteBuf
  • PooledHeapByteBuf
  • クラス図の構造を見てPooledUnsafeDirectByteBuf

ソースコード解析

ソースコード解析AbstractByteBuf

    @オーバーライド
    公共ByteBufのreadBytes(ByteBuf DST、INT dstIndex、int型の長さ){
        checkReadableBytes(長さ)。
        サブクラス実装と呼ば//抽象メソッド
        GetBytesメソッド(readerIndex、DST、dstIndex、長さ);
        readerIndex + =長さ。
        これを返します。
    }

看一下写操作
    @オーバーライド
    公共ByteBufのwriteBytes(バイト[] SRC、INT srcIndex、INT長){
        ensureWritable(長さ)。
        setBytes(writerIndex、SRC、srcIndex、長さ);
        writerIndex + =長さ。
        これを返します。
    }


    @オーバーライド
    公共ByteBuf ensureWritable(INT minWritableBytes){
        IF(minWritableBytes <0){
            ((String.Formatの新しいIllegalArgumentExceptionをスローし
                    "minWritableBytes:%のD(予想:> = 0)"、minWritableBytes))。
        }

        IF(minWritableBytes <= writableBytes()){
            これを返します。
        }

        IF(minWritableBytes> MAXCAPACITY  -  writerIndex){
            ((String.Formatのを新しいはIndexOutOfBoundsExceptionを投げます
                    、: "%sのwriterIndex(%d)は+ minWritableBytes(%d)はMAXCAPACITY率(%D)を超えます"
                    writerIndex、minWritableBytes、MAXCAPACITY、この));
        }

        // 2の電源に電流容量を正規化。
        INT newCapacity = calculateNewCapacity(writerIndex + minWritableBytes)。

        //新しい容量を調整します。
        容量(newCapacity)。
        これを返します。
    }



   / **
    *新しい容量ではなく、すべてのこのような単純な考え方の突然倍増のが、少しの増加を計算します。
    * 
    * / 
    プライベートint型calculateNewCapacity(int型minNewCapacity){
        最終int型MAXCAPACITY = this.maxCapacity。
        最終INT閾値= 1048576 * 4。// 4のMIBページ

        IF(minNewCapacity ==閾値){
            しきい値を返します。
        }

        //しきい値を超える場合は、倍増ちょうどしきい値によって増加しません。
        IF(minNewCapacity>閾値){
            int型newCapacity = minNewCapacity /しきい値*しきい値。
            IF(newCapacity> MAXCAPACITY  - 閾値){
                newCapacity = MAXCAPACITY。
            }他{
                newCapacity + =閾値。
            }
            newCapacityを返します。
        }

        //未しきい値を超えます。64から始まる、4 MIBへのダブルアップ。
        int型newCapacity = 64;
        一方、(newCapacity <minNewCapacity){
            newCapacity << = 1。
        }

        Math.min(newCapacity、MAXCAPACITY)を返します。
    }


 丢弃已读区域,复用缓冲区
    @オーバーライド
    discardReadBytes ByteBufパブリック(){
        ensureAccessible();
        IF(readerIndex == 0){
            これを返します。
        }

        もし(readerIndex!= writerIndex){
        	//サブクラス実装、コピーするバイト配列、前方の書き込み領域
            setBytes(0、この、readerIndex、writerIndex  -  readerIndex)。
            writerIndex  -  = readerIndex。
            adjustMarkers(readerIndex)。
            readerIndex = 0;
        }他{
            adjustMarkers(readerIndex)。
            writerIndex = readerIndex = 0。
        }
        これを返します。
    }


    保護された最終的な空隙adjustMarkers(INTデクリメント){
        int型markedReaderIndex = this.markedReaderIndex。
        IF(markedReaderIndex <=デクリメント){
            this.markedReaderIndex = 0;
            int型markedWriterIndex = this.markedWriterIndex。
            IF(markedWriterIndex <=デクリメント){
                this.markedWriterIndex = 0;
            }他{
                this.markedWriterIndex = markedWriterIndex  - デクリメント。
            }
        }他{
            this.markedReaderIndex = markedReaderIndex  - デクリメント。
            markedWriterIndex  -  =デクリメント。
        }
    }

ソースコード解析AbstractReferenceCountedByteBuf

 从名字看出该类主要对引用进行计数,类似于JVM 内存回收的对象引用计数器,用于跟踪对象的分配和销毁,做自动内存回收。
パブリック抽象クラスAbstractReferenceCountedByteBufはAbstractByteBufを{拡張します
	//セキュリティスレッドを確保するために、CAS操作をアトミッククラスを使用します
    プライベート静的最終AtomicIntegerFieldUpdater <AbstractReferenceCountedByteBuf> refCntUpdater =
            AtomicIntegerFieldUpdater.newUpdater(AbstractReferenceCountedByteBuf.class、 "REFCNT");

    プライベート静的最終長いREFCNT_FIELD_OFFSET。

    静的{
        長いrefCntFieldOffset = -1;
        {試します
            IF(PlatformDependent.hasUnsafe()){
                refCntFieldOffset = PlatformDependent.objectFieldOffset(
                        AbstractReferenceCountedByteBuf.class.getDeclaredField( "REFCNT"));
            }
        }キャッチ(ThrowableをT){
            //無視
        }

        REFCNT_FIELD_OFFSET = refCntFieldOffset。
    }

    @SuppressWarnings( "FieldMayBeFinal")
    プライベート揮発int型REFCNT = 1;


    @オーバーライド
    公共最終ブール放出(){
        ために (;;) {
            int型REFCNT = this.refCnt。
            IF(REFCNT == 0){
                新しいIllegalReferenceCountException(0、-1)投げます。
            }

            IF(refCntUpdater.compareAndSet(この、REFCNT、REFCNT  -  1)){
                IF(REFCNT == 1){
                    DEALLOCATE();
                    trueを返します。
                }
                falseを返します。
            }
        }
    }



    @オーバーライド
    {)(保持ByteBuf公衆
        ために (;;) {
            int型REFCNT = this.refCnt。
            IF(REFCNT == 0){
                新しいIllegalReferenceCountException(0、1)を投げます。
            }
            IF(REFCNT == Integer.MAX_VALUEの){
                新しいIllegalReferenceCountExceptionを投げる(Integer.MAX_VALUEで、1);
            }
            // CAS操作
            IF(refCntUpdater.compareAndSet(この、REFCNT、REFCNT + 1)){
                ブレーク;
            }
        }
        これを返します。
    }    


    ....    

这个类有三个重要的字段,一个原子类用于多线程操作,保证线程安全。REFCNT_FIELD_OFFSET 是一个内存偏移量,用于标识 refCnt字段在AbstractReferenceCountedByteBuf这个类
的内存地址,最后一个refCnt 是用 volatile 修饰的变量,保存对象应用次数。

ソースコード解析ByteBuf UnpooledHeapByteBuf非メモリセルスタックメモリ

パブリッククラスUnpooledHeapByteBufはAbstractReferenceCountedByteBufを{延び

	//メモリ割り当て
    民間最終ByteBufAllocatorのアロケーション;
    //バイトバッファ
    プライベートバイト[]配列。
    //役割とJDKのByteBufferの変換
    民間のByteBuffer tmpNioBuf。

    ...

    プライベートINT GetBytesメソッド(int型のインデックス、GatheringByteChannelうち、int型の長さ、ブール内部)はIOExceptionが{スロー
        ensureAccessible();
        ByteBuffer tmpBuf;
        //操作に使用tmpNioBufフィールド自体を返し、そうUnpooledHeapByteBufはJDK ByteBuffに基づいて延長されます。
        IF(内部){
            tmpBuf = internalNioBuffer()。
        }他{
            tmpBuf = ByteBuffer.wrap(アレイ)
        }
        out.write返す((のByteBuffer)tmpBuf.clear()位置(インデックス).limit(指標+長さ)。)。
    }


    @オーバーライド
    公共のint readBytes(GatheringByteChannelうち、int型の長さ)は、IOExceptionが{スロー
        checkReadableBytes(長さ)。
        INT readBytes = GetBytesメソッド(readerIndex、アウト、長さ、TRUE);
        readerIndex + = readBytes。
        readBytesを返します。
    }

概要

文章主要介绍netty buffer 相关的知识,主要是父类方法和 unpooled 相关的实现。

参考資料

  • "ネッティーDefinitive Guideの"

おすすめ

転載: www.cnblogs.com/Benjious/p/11634877.html
おすすめ