国产探花免费观看_亚洲丰满少妇自慰呻吟_97日韩有码在线_资源在线日韩欧美_一区二区精品毛片,辰东完美世界有声小说,欢乐颂第一季,yy玄幻小说排行榜完本

首頁 > 學(xué)院 > 開發(fā)設(shè)計 > 正文

netty之DirectByteBuf 和 HeapByteBuf淺談

2019-11-08 01:55:14
字體:
供稿:網(wǎng)友

ByteBuf是netty中數(shù)據(jù)傳輸?shù)娜萜鳎脕硖娲鶱IO中的ByteBuffer。其主要還是一個byte數(shù)組,以及包含了一些數(shù)據(jù)的操作方法。通過兩個指針readerIndex和writerIndex來讀寫分離,更好的處理數(shù)據(jù)。其結(jié)構(gòu)大致如下圖所示。

ByteBuf示意圖

而從內(nèi)存分配的角度來講,ByteBuf又分為兩種,DirectByteBuf和HeapByteBuf。簡而言之就是一種是分配在Direct Memory上的,一種是分配在Heap Memory上的。

這里稍微解釋一下direct memory。直接內(nèi)存(Direct Memory)并不是虛擬機運行時數(shù)據(jù)區(qū)的一部分,也不是java虛擬機規(guī)范中定義的內(nèi)存區(qū)域,但是這部分內(nèi)存也被頻繁地使用,而且也可能導(dǎo)致異常出現(xiàn)。它是在JDK 1.4 中新加入了NIO(New Input/Output)類,引入了一種基于通道(Channel)與緩沖區(qū)(Buffer)的I/O 方式,它可以使用Native 函數(shù)庫直接分配堆外內(nèi)存,然通過一個存儲在Java 堆里面的DirectByteBuffer 對象作為這塊內(nèi)存的引用進行操作。這樣能在一些場景中顯著提高性能,因為避免了在Java 堆和Native 堆中來回復(fù)制數(shù)據(jù)。

直接內(nèi)存的好處就是利用的是native庫,讀寫快速。但是它不在虛擬機的管理范圍之內(nèi),這部分內(nèi)存只有在進行full gc時才會進行回收,而他的容量如果沒有明確限制,隨著數(shù)據(jù)的不斷讀寫勢必造成內(nèi)存中可利用的空間不斷變小。所以netty做了引用計數(shù)機制來處理direct memory上的數(shù)據(jù)。其實對heap上的也做了引用計數(shù)。

PRivate static final AtomicIntegerFieldUpdater<AbstractReferenceCountedByteBuf> refCntUpdater;private volatile int refCnt = 1;

其主要用了這兩個變量來處理引用計數(shù)問題。計數(shù)器基于 AtomicIntegerFieldUpdater,為什么不直接用AtomicInteger?因為ByteBuf對象很多,如果都把int包一層AtomicInteger花銷較大,而AtomicIntegerFieldUpdater只需要一個全局的靜態(tài)變量。

retain

@Override public ByteBuf retain() { for (;;) { int refCnt = this.refCnt; if (refCnt == 0) { throw new IllegalReferenceCountException(0, 1); } if (refCnt == Integer.MAX_VALUE) { throw new IllegalReferenceCountException(Integer.MAX_VALUE, 1); } if (refCntUpdater.compareAndSet(this, refCnt, refCnt + 1)) { break; } } return this; }

release

@Override public boolean release() { for (;;) { int refCnt = this.refCnt; if (refCnt == 0) { throw new IllegalReferenceCountException(0, -1); } if (refCntUpdater.compareAndSet(this, refCnt, refCnt - 1)) { if (refCnt == 1) { deallocate(); return true; } return false; } } }

這兩種ByteBuf有各自的特點,用于針對不同的場景。HeapByteBuf :特點是內(nèi)存的分配和回收速度快。可以被jvm自動回收。缺點就是在進行socket的I/O讀寫時,需要將堆內(nèi)存的緩沖區(qū)拷貝到內(nèi)核中,有一定拷貝的代價。DirectByteBuf:特點是分配在堆內(nèi)存外,相比于堆內(nèi)存分配速度會慢一點,并需要手動管理其引用計數(shù),清理不使用的內(nèi)存。但是其直接用native方法,不需要拷貝。

ByteBuf從內(nèi)存回收策略上來說也分為兩種pool和unpool。其中poolByteBuf主要是建立了一塊內(nèi)存池來管理ByteBuf。其主要為一塊poolArena,其中維護這多個poolChunk。其變量大致如下。

bstract class PoolArena<T> implements PoolArenaMetric { static final boolean HAS_UNSAFE = PlatformDependent.hasUnsafe(); enum SizeClass { Tiny, Small, Normal } static final int numTinySubpagePools = 512 >>> 4; final PooledByteBufAllocator parent; private final int maxOrder; final int pageSize; final int pageShifts; final int chunkSize; final int subpageOverflowMask; final int numSmallSubpagePools; private final PoolSubpage<T>[] tinySubpagePools; private final PoolSubpage<T>[] smallSubpagePools; private final PoolChunkList<T> q050; private final PoolChunkList<T> q025; private final PoolChunkList<T> q000; private final PoolChunkList<T> qInit; private final PoolChunkList<T> q075; private final PoolChunkList<T> q100; private final List<PoolChunkListMetric> chunkListMetrics;
發(fā)表評論 共有條評論
用戶名: 密碼:
驗證碼: 匿名發(fā)表
主站蜘蛛池模板: 包头市| 合江县| 呼和浩特市| 延津县| 邵东县| 岳普湖县| 临泉县| 潼南县| 山东| 阿尔山市| 阿鲁科尔沁旗| 璧山县| 吴江市| 高淳县| 贵阳市| 龙海市| 大渡口区| 偏关县| 易门县| 安福县| 饶平县| 云林县| 鄂托克前旗| 大田县| 虎林市| 东乌珠穆沁旗| 当阳市| 淮南市| 南和县| 鲜城| 蒙山县| 宝坻区| 会东县| 七台河市| 阿坝| 博罗县| 盐池县| 高雄市| 岗巴县| 博罗县| 迁西县|