PooledByteBuf源码分析
1.成員變量
先來看一下PooledByteBuf的類聲明
abstract class PooledByteBuf<T> extends AbstractReferenceCountedByteBuf為什么要加模版呢? 
 他的一個成員protected T memory;由于不知道的T是什么數據類型,所以定義了模板類可以從他的字類中看出來
在前面的學習中,很容易知道,基于內存的ByteBuf是通過操作ByteBuffer的position來實現讀寫等操作的,而給予堆的ByteBuf是通過Byte數組來實現讀寫等操作的,因此聲明<T>
成員變量有
private final Recycler.Handle<PooledByteBuf<T>> recyclerHandle;protected PoolChunk<T> chunk;protected long handle;protected T memory;protected int offset;protected int length;int maxLength;Thread initThread;private ByteBuffer tmpNioBuf;resyclerHandle可以理解為垃圾收集器,負責分配回收內存
PoolChunk<T> chunk可以理解為一個很大的內存區域的一個實例,這個類的成員中又一個PoolArean,就是內存中的一大片區域 
 netty為了集中管理內存的分配和釋放,同時提高分配和釋放內存的性能,預先申請一大片內存,然后提供分配和釋放接口來使用,這樣一來,就能不需要頻繁地進行系統的申請和釋放內存,應用程序的性能就會大大提升。
2. 初始化
void init(PoolChunk<T> chunk, long handle, int offset, int length, int maxLength) {assert handle >= 0;assert chunk != null;this.chunk = chunk;this.handle = handle;memory = chunk.memory;this.offset = offset;this.length = length;this.maxLength = maxLength;setIndex(0, 0);tmpNioBuf = null;initThread = Thread.currentThread();}可以知道,memory實際上就是chunk中的數據,initThread實際上就是當前的進程。
3.動態擴展內存
我們在前面的UnpooledHeapByteBuf和UnpooledDirectByteBuf中都看到了這個方法,一個是進行array的增大,一個是對ByteBuf的擴展。
public final ByteBuf capacity(int newCapacity) {ensureAccessible();// If the request capacity does not require reallocation, just update the length of the memory.if (chunk.unpooled) {if (newCapacity == length) {return this;}} else {if (newCapacity > length) {if (newCapacity <= maxLength) {length = newCapacity;return this;}} else if (newCapacity < length) {if (newCapacity > maxLength >>> 1) {if (maxLength <= 512) {if (newCapacity > maxLength - 16) {length = newCapacity;setIndex(Math.min(readerIndex(), newCapacity), Math.min(writerIndex(), newCapacity));return this;}} else { // > 512 (i.e. >= 1024)length = newCapacity;setIndex(Math.min(readerIndex(), newCapacity), Math.min(writerIndex(), newCapacity));return this;}}} else {return this;}}1.如果chunk內存區是unpooled(沒有實現內存池)的話,只有當newCapacity == length時直接返回,其他情況都要重新分配內存。 
 2.如果chunk內存區實現了內存池,當新的容量大于原來的容量,且小于最大容量時,直接設置原來的容量為新的容量就行。 
 3.如果新的容量小于原來的容量,那么就要進行減容處理了,先把最大容量>>>1,向右位位移一位(除2),然后根據除2以后的最大容量和新容量對比,分別進行不同的操作。
4.分配回收內存
來看三個方法
@Overridepublic final ByteBufAllocator alloc() {return chunk.arena.parent;} @Overrideprotected final void deallocate() {if (handle >= 0) {final long handle = this.handle;this.handle = -1;memory = null;boolean sameThread = initThread == Thread.currentThread();initThread = null;chunk.arena.free(chunk, handle, maxLength, sameThread);recycle();}} private void recycle() {recyclerHandle.recycle(this);}第一個方法返回ByteBufAllocator對象 
 第二個方法先銷毀原來的內存區,然后重新分配 
 第三個方法直接回收內存區
總的來說在這個類很容易理解,由于它實現了分配回收內存,還有動態擴展緩存的方法,所以它的字類PooledHeapByteBuf和PooledDirectByteBuf也就不用在實現這些方法啦。
總結
以上是生活随笔為你收集整理的PooledByteBuf源码分析的全部內容,希望文章能夠幫你解決所遇到的問題。
                            
                        - 上一篇: UnpooledDirectByteBu
 - 下一篇: PooledDirectByteBuf源