本文共 3035 字,大约阅读时间需要 10 分钟。
被引用计数包含的对象,能够显示的被垃圾回收。当初始化的时候,计数为1。retain()方法能够增加计数,release() 方法能够减少计数,如果计数被减少到0则对象会被显示回收,再次访问被回收的这些对象将会抛出异常。如果一个对象实现了ReferenceCounted,并且包含有其他对象也实现来ReferenceCounted,当这个对象计数为0被回收的时候,所包含的对象同样会通过release()释放掉。
由以下实现关系:
public abstract class AbstractReferenceCountedByteBuf extends AbstractByteBuf{ }public abstract class AbstractByteBuf extends ByteBuf{ }public abstract class ByteBuf implements ReferenceCounted, Comparable{ }
AbstractReferenceCountedByteBuf是ReferenceCounted一个抽象实现类:
public abstract class AbstractReferenceCountedByteBuf extends AbstractByteBuf { private static final AtomicIntegerFieldUpdaterrefCntUpdater = AtomicIntegerFieldUpdater.newUpdater(AbstractReferenceCountedByteBuf.class, "refCnt"); private volatile int refCnt = 1; ...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. if (nextCnt <= increment) { throw new IllegalReferenceCountException(refCnt, increment); } if (refCntUpdater.compareAndSet(this, refCnt, nextCnt)) { break; } } return this; } ... private boolean release0(int decrement) { for (;;) { int refCnt = this.refCnt; if (refCnt < decrement) { throw new IllegalReferenceCountException(refCnt, -decrement); } if (refCntUpdater.compareAndSet(this, refCnt, refCnt - decrement)) { if (refCnt == decrement) { deallocate(); return true; } return false; } } }
对于release0方法,如果计数变成0则会回收相应的资源
对于retain0方法中通过compareAndSet来进行原子更新操作,确保多线程的正常计数操作,并通过自旋锁无限循环仅正确的cas操作才跳出。对于compareAndSet方法:
public abstract class AtomicIntegerFieldUpdater{ ... public abstract boolean compareAndSet(T obj, int expect, int update); ...}
通过原子的方式来更新AtomicIntegerFieldUpdater更新器所持有的T对象中的某个成员变量,如果当前值等于期望值expect,那么会原子的更新成update。前提是,其他线程都是通过调用compareAndSet(弱原子性操作)来更新变量,否则无法保证操作是原子的(比如一些地方直接赋值)。compareAndSet是系统底层的实现,通过内存偏移量来完成整个操作。
对于AtomicIntegerFieldUpdater,是基于反射的能够原子更新给定类中的volatile int成员变量的一个工具类。这个类用来原子更新同一个节点中的多个变量,而做到不同的变量间原子操作单独不影响。
AtomicIntegerFieldUpdater重要要点:
对比JDK自带的AtomicInteger,如果netty底层通过AtomicInteger来维护,那么对于所有的ByteBuf对象都需要有对应的AtomicInteger来维护,而netty底层是需要用到大量的ByteBuf来做操的,可能会有许多的AtomicInteger变量,相比于一个全局的AtomicReferenceFieldupdater,在这里是static静态的,就能够维护所有的ByteBuf的引用计数,从而有一个性能上的提升。
转载地址:http://ahrgi.baihongyu.com/