Netty-源碼分析ByteBuf-slice和retainedSlice使用細節

Netty-源碼分析ByteBuf-slice和retainedSlice使用細節

slice() = slice(buf.readerIndex(), buf.readableBytes())

源碼片段,返回原始ByteBuf可讀字節的一部分, 修改返回的緩衝區或此緩衝區的內容會影響彼此的內容,他們維護單獨的index和makers,此方法不會修改原始緩衝區的readerIndex或writerIndex。

 @Override
    public ByteBuf slice() {
        return slice(readerIndex, readableBytes());
    }

 @Override
    public ByteBuf slice(int index, int length) {
        ensureAccessible();
        return new UnpooledSlicedByteBuf(this, index, length);
    }

    boolean release0() {
        return unwrap().release();
    }
public static void main(String[] args) throws Exception {
		PooledByteBufAllocator allocator = PooledByteBufAllocator.DEFAULT;
		ByteBuf original = allocator.directBuffer(32);
		original.writeByte(1);
		original.writeByte(2);
		original.writeByte(3);

		//相當於original.slice(original.readerIndex(), original.readableBytes());
		ByteBuf sub = original.slice();

		//新緩衝區修改值後互相影響
		sub.setByte(0, 10);
		System.out.println("sub.readByte = " + sub.readByte());
		System.out.println("original.readByte = " + original.readByte());

		//原始緩衝區在讀一次
		System.out.println("original.readByte = " + original.readByte());

		//Index互不影響
		System.out.println("sub.readerIndex = " + sub.readerIndex());
		System.out.println("original.readerIndex = " + original.readerIndex());

		//必須釋放
		original.release();

	}

 

與slice一模一樣,只是調用了retain,在使用完畢後需要多釋放一次。

  @Override
    public ByteBuf retainedSlice() {
        return slice().retain();
    }

    @Override
    public final ByteBuf retain() {
        return retain0();
    }

    ByteBuf retain0() {
        unwrap().retain();
        return this;
    }

 

在使用完畢後,必須要釋放倆次。

	public static void main(String[] args) throws Exception {
		PooledByteBufAllocator allocator = PooledByteBufAllocator.DEFAULT;
		ByteBuf original = allocator.directBuffer(32);
		original.writeByte(1);
		original.writeByte(2);
		original.writeByte(3);

		ByteBuf sub = original.retainedSlice();
		sub.release();
		original.release();

		System.out.println("sub.refCnt = " + sub.refCnt());
		System.out.println("original.refCnt = " + original.refCnt());

 

AbstractPooledDerivedByteBuf源碼分析

    final <U extends AbstractPooledDerivedByteBuf> U init(
            AbstractByteBuf unwrapped, ByteBuf wrapped, int readerIndex, int writerIndex, int maxCapacity) {
        //原始緩衝區計數器++
        wrapped.retain(); // Retain up front to ensure the parent is accessible before doing more work.
        parent = wrapped;
        rootParent = unwrapped;

        try {
            maxCapacity(maxCapacity);
            setIndex0(readerIndex, writerIndex); // It is assumed the bounds checking is done by the caller.
            resetRefCnt();
    @Override
    protected final void deallocate() {
        // We need to first store a reference to the parent before recycle this instance. This is needed as
        // otherwise it is possible that the same AbstractPooledDerivedByteBuf is again obtained and init(...) is
        // called before we actually have a chance to call release(). This leads to call release() on the wrong parent.
        ByteBuf parent = this.parent;
        recyclerHandle.recycle(this);
        //子緩衝區釋放會 減少原始緩衝區計數器
        parent.release();
    }

 

 

 

發佈了175 篇原創文章 · 獲贊 70 · 訪問量 44萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章