PooledByteBuf

2019-08-01  本文已影响0人  Pillar_Zhong

关键属性

// 所属chunk
protected PoolChunk<T> chunk;
// 在chunk中内存地址的偏移
protected long handle;
// 
protected T memory;
protected int offset;
// 实际当时申请的内存大小
protected int length;
// 实际底层返回的最大可用的内存大小
int maxLength;
// 跟线程绑定的本地缓存
PoolThreadCache cache;
// 
private ByteBuffer tmpNioBuf;

扩容

public final ByteBuf capacity(int newCapacity) {
    ensureAccessible();

    // 如果是非池化,且容量不变,那么直接返回,没有扩容的需要
    if (chunk.unpooled) {
        if (newCapacity == length) {
            return this;
        }
    } else {
        // 如果是池化,且新的容量要比之前申请的大,但还没有超过底层最大所能容纳空间,那么只需要
        // 更新length,返回即可。
        if (newCapacity > length) {
            if (newCapacity <= maxLength) {
                length = newCapacity;
                return this;
            }
        // 如果新的容量比之前申请的小,说明是缩容的动作
        } else if (newCapacity < length) {
            // 如果新的容量要大于max的一半,起码small类型那边就不用动了,因为small是翻倍递增的
            if (newCapacity > maxLength >>> 1) {
                // 如果是tiny类型
                if (maxLength <= 512) {
                    // 首先要明确,tiny是16B递增的,只要在16的范围内浮动就可以复用当前的空间
                    // 想一想,假如现在分配的tiny块是498的max,只要新的容量在498-16到498的范围
                    // 内,那么就只需要更新index就好
                    if (newCapacity > maxLength - 16) {
                        length = newCapacity;
                        setIndex(Math.min(readerIndex(), newCapacity), Math.min(writerIndex(), newCapacity));
                        return this;
                    }
                } else { // > 512 (i.e. >= 1024)
                    // 如前small所述
                    length = newCapacity;
                    setIndex(Math.min(readerIndex(), newCapacity), Math.min(writerIndex(), newCapacity));
                    return this;
                }
            }
        } else {
            return this;
        }
    }

    // Reallocation required.
    // 到这里说明前面的努力全部失败,那么去arena实际去找更合适的内存区域
    chunk.arena.reallocate(this, newCapacity, true);
    return this;
}

上一篇下一篇

猜你喜欢

热点阅读