Netty原始碼之directArena分配direct記憶體的流程
阿新 • • 發佈:2018-12-12
這個流程分為以下幾個步驟: 1、從物件池裡面拿到PooledByteBuf進行復用 2、從快取上進行記憶體分配 3、從記憶體堆裡面進行分配 接下來我們跟到程式碼裡面去看一下,回到newDirectBuffer這個方法:
protected ByteBuf newDirectBuffer(int initialCapacity, int maxCapacity) { //拿到當前執行緒中的記憶體池 PoolThreadCache cache = threadCache.get(); //拿到當前記憶體池裡面的directArena進行分配 PoolArena<ByteBuffer> directArena = cache.directArena; ByteBuf buf; if (directArena != null) { buf = directArena.allocate(cache, initialCapacity, maxCapacity); } else { if (PlatformDependent.hasUnsafe()) { buf = UnsafeByteBufUtil.newUnsafeDirectByteBuf(this, initialCapacity, maxCapacity); } else { buf = new UnpooledDirectByteBuf(this, initialCapacity, maxCapacity); } } return toLeakAwareBuffer(buf); }
這個方法做了兩件事: 1、拿到當前執行緒的記憶體池 2、拿到記憶體池裡面的directArena進行記憶體分配 這個方法上一篇講過了,我們直接進入記憶體分配的方法裡面去看一下:
PooledByteBuf<T> allocate(PoolThreadCache cache, int reqCapacity, int maxCapacity) { //拿到一個物件 PooledByteBuf<T> buf = newByteBuf(maxCapacity); //給這個物件分配記憶體空間 allocate(cache, buf, reqCapacity); return buf; }
這個方法很清晰,就是先通過newByteBuf方法拿一個PooledByteBuf物件,然後通過allocate給這個物件分配記憶體:
protected PooledByteBuf<ByteBuffer> newByteBuf(int maxCapacity) { if (HAS_UNSAFE) { return PooledUnsafeDirectByteBuf.newInstance(maxCapacity); } else { return PooledDirectByteBuf.newInstance(maxCapacity); } }
由於預設情況下是unsafe的,所以我們進入第一個分支去看一下:
static PooledUnsafeDirectByteBuf newInstance(int maxCapacity) {
//拿到一個buf
PooledUnsafeDirectByteBuf buf = RECYCLER.get();
//重新利用這個buf
buf.reuse(maxCapacity);
return buf;
}
首先會從回收的物件池裡面拿一個物件進行復用,如果沒有拿到就重新建立一個。
final void reuse(int maxCapacity) {
maxCapacity(maxCapacity);
setRefCnt(1);
setIndex0(0, 0);
discardMarks();
}
設定一些初始引數。 到這裡我們就拿到了一個buf物件,接下來就要對他進行記憶體分配。首先通過快取進行記憶體分配,如果失敗就會通過Aren/進行分配。
if (normCapacity <= chunkSize) {
if (cache.allocateNormal(this, buf, reqCapacity, normCapacity)) {
// was able to allocate out of the cache so move on
return;
}
allocateNormal(buf, reqCapacity, normCapacity);
}
以這段程式碼為例。 這節我們主要是簡單介紹一下大體上記憶體分配的流程,那麼,之後我們就會對各種記憶體規格的分配進行詳細的講解。