// Normalize the current capacity to the power of 2. int newCapacity = alloc().calculateNewCapacity(writerIndex + minWritableBytes, maxCapacity);//计算新的容量
// Adjust to the new capacity. capacity(newCapacity);//自动调节容量 }
2、ByteBuf的读写索引是完全分开的,使用起来很方便。
ReferenceCounted
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19
/** * A reference-counted object that requires explicit deallocation. * 引用计数回收对象 * <p> * When a new {@link ReferenceCounted} is instantiated, it starts with the reference count of {@code 1}. * {@link #retain()} increases the reference count, and {@link #release()} decreases the reference count. * If the reference count is decreased to {@code 0}, the object will be deallocated explicitly, and accessing * the deallocated object will usually result in an access violation. * </p> * 当一个ReferenceCounted创建的时候他的初始引用数量是1,retain方法增加一个引用数量,release方法减少一个引用数量,如果引用数量是 * 变成0,那么对象就会被死亡回收,加入引用一个已经被定义为死亡的对象的结果通常是会出现问题的。 * <p> * If an object that implements {@link ReferenceCounted} is a container of other objects that implement * {@link ReferenceCounted}, the contained objects will also be released via {@link #release()} when the container's * reference count becomes 0. * </p> * 如果一个实现了ReferenceCounted接口的这个对象作为一个容器,他的内部的对象也是实现了ReferenceCounted接口,那么当外边的容器的 * count引用数量变为0的时候,容器内部的对象也会别回收。 */
public ByteBuf retain(int increment) { return retain0(checkPositive(increment, "increment")); }
private ByteBuf retain0(int increment) { for (;;) {//回旋锁 int refCnt = this.refCnt; final int nextCnt = refCnt + increment;
// Ensure we not resurrect (which means the refCnt was 0) and also that we encountered an overflow. //如果refCnt 是0那么就会出现nextCnt = increment的情况,但是这样违背了netty的回收计数器的原则,程序就可以往下走,这是 //不合法的,当为0的时候正常的情况是要被回收的。 if (nextCnt <= increment) { throw new IllegalReferenceCountException(refCnt, increment); } // private static final AtomicIntegerFieldUpdater<AbstractReferenceCountedByteBuf> refCntUpdater = // AtomicIntegerFieldUpdater.newUpdater(AbstractReferenceCountedByteBuf.class, "refCnt"); //首先使用的是AtomicIntegerFieldUpdater进行的cas操作(基于硬件的更新实现),其次refCnt是 // private volatile int refCnt = 1;即是volatile 类型的,在多线程的情况下保证相互之间的可见性。 if (refCntUpdater.compareAndSet(this, refCnt, nextCnt)) {//cas操作增加引用计数 break; } } return this; }