PoolArena#allocate:分配内存的入口
PooledByteBuf<T> allocate(PoolThreadCache cache, int reqCapacity, int maxCapacity) {
PooledByteBuf<T> buf = newByteBuf(maxCapacity);
allocate(cache, buf, reqCapacity);
return buf;
}
我们看到了buf的创建由newByteBuf,这个buf对象用来承载分配的内存。我们看一下直接内存的分配,堆内内存类似。
protected PooledByteBuf<ByteBuffer> newByteBuf(int maxCapacity) {
if (HAS_UNSAFE) {
return PooledUnsafeDirectByteBuf.newInstance(maxCapacity);
} else {
return PooledDirectByteBuf.newInstance(maxCapacity);
}
}
PooledUnsafeDirectByteBuf#newInstance:一个静态方法创建了一个buf对象,用来承载分配的内存。
static PooledUnsafeDirectByteBuf newInstance(int maxCapacity) {
PooledUnsafeDirectByteBuf buf = RECYCLER.get();
buf.reuse(maxCapacity);
return buf;
}
对象是由对象池RECYCLER获取的。RECYCLER是一个staic final变量。
private static final Recycler<PooledUnsafeDirectByteBuf> RECYCLER = new Recycler<PooledUnsafeDirectByteBuf>() {
@Override
protected PooledUnsafeDirectByteBuf newObject(Handle<PooledUnsafeDirectByteBuf> handle) {
return new PooledUnsafeDirectByteBuf(handle, 0);
}
};
首先看Recycler的构造:主要是对一些容量的设置以及一个FastTreadLocal类型的Stack。还有一个一个FastTreadLocal类型的weakHashMap。
public abstract class Recycler<T> {
private static final InternalLogger logger = InternalLoggerFactory.getInstance(Recycler.class);
private static final Recycler.Handle NOOP_HANDLE = new Recycler.Handle() {
public void recycle(Object object) {
}
};
private static final AtomicInteger ID_GENERATOR = new AtomicInteger(-2147483648);
private static final int OWN_THREAD_ID;
private static final int DEFAULT_INITIAL_MAX_CAPACITY_PER_THREAD = 32768;
private static final int DEFAULT_MAX_CAPACITY_PER_THREAD;
private static final int INITIAL_CAPACITY;
private static final int MAX_SHARED_CAPACITY_FACTOR;
private static final int MAX_DELAYED_QUEUES_PER_THREAD;
private static final int LINK_CAPACITY;
private static final int RATIO;
private final int maxCapacityPerThread;
private final int maxSharedCapacityFactor;
private final int ratioMask;
private final int maxDelayedQueuesPerThread;
// 一个ftl的栈
private final FastThreadLocal<Recycler.Stack<T>> threadLocal;
// 一个ftl的weakHashMap
private static final FastThreadLocal<Map<Recycler.Stack<?>, Recycler.WeakOrderQueue>> DELAYED_RECYCLED;
...
...
我们看一下Stack:
static final class Stack<T> {
// 保存外部类的引用
final Recycler<T> parent;
// 保存自己属于的线程
final Thread thread;
final AtomicInteger availableSharedCapacity;
final int maxDelayedQueues;
private final int maxCapacity;
private final int ratioMask;
// 装载对象的数组
private Recycler.DefaultHandle<?>[] elements;
private int size;
private int handleRecycleCount = -1;
// 三个指针
private Recycler.WeakOrderQueue cursor;
private Recycler.WeakOrderQueue prev;
// volatile修饰了
private volatile Recycler.WeakOrderQueue head;
...
...
...
大致结构:head指针主要是连接各个WeakOrderQueue,而prev和cursor是变量整条head链表的
我们在看一下这个map :是一个WeakHashMap。键是stack的weak引用。Value是WeakOrderQueue
private static final FastThreadLocal<Map<Stack<?>, WeakOrderQueue>> DELAYED_RECYCLED =
new FastThreadLocal<Map<Stack<?>, WeakOrderQueue>>() {
@Override
protected Map<Stack<?>, WeakOrderQueue> initialValue() {
return new WeakHashMap<Stack<?>, WeakOrderQueue>();
}
};
多线程创建和回收对象(A线程创建对象,B线程回收这个对象),为了不出现多线程同时去存取操作Stack而产生的竞争情况,就区分了当前线程是不是Stack的拥有线程,如果是,就直接放回到Stack中,如果不是,就放入对应的WeakOrderQueue中,前面说了Stack和WeakOrderQueue有对应关系。而且多个线程中都可能有同一个Stack的不同WeakOrderQueue。他们之间是用单链表连起来的。大致关系就像这样:head指针就是stack里面的
我们看一下WeakOrderQueue:在构建的时候加入到stack中的head链表中,使用的是头插法,用synchronized 修饰,保证head链表修改的线程安全。
private WeakOrderQueue(Stack<?> stack, Thread thread) {
head = tail = new Link();
owner = new WeakReference<Thread>(thread);
synchronized (stack) {
next = stack.head;
stack.head = this;
}
// Its important that we not store the Stack itself in the WeakOrderQueue as the Stack also is used in
// the WeakHashMap as key. So just store the enclosed AtomicInteger which should allow to have the
// Stack itself GCed.
availableSharedCapacity = stack.availableSharedCapacity;
}
看一下结构