Netty 使用自建的 buffer API,而不是使用 NIO 的 ByteBuffer 來表示一個連續(xù)的字節(jié)序列。與 ByteBuffer 相比這種方式擁有明顯的優(yōu)勢。Netty 使用新的 buffer 類型 ByteBuf,被設(shè)計為一個可從底層解決 ByteBuffer 問題,并可滿足日常網(wǎng)絡(luò)應(yīng)用開發(fā)需要的緩沖類型。這些很酷的特性包括:
更多信息請參考:io.netty.buffer 包描述
ByteBuf 具有豐富的操作集,可以快速的實現(xiàn)協(xié)議的優(yōu)化。例如,ByteBuf 提供各種操作用于訪問無符號值和字符串,以及在緩沖區(qū)搜索一定的字節(jié)序列。你也可以擴展或包裝現(xiàn)有的緩沖類型用來提供方便的訪問。自定義緩沖式仍然實現(xiàn)自 ByteBuf 接口,而不是引入一個不兼容的類型
舉一個網(wǎng)絡(luò)應(yīng)用到極致的表現(xiàn),你需要減少內(nèi)存拷貝操作次數(shù)。你可能有一組緩沖區(qū)可以被組合以形成一個完整的消息。網(wǎng)絡(luò)提供了一種復(fù)合緩沖,允許你從現(xiàn)有的任意數(shù)的緩沖區(qū)創(chuàng)建一個新的緩沖區(qū)而無需沒有內(nèi)存拷貝。例如,一個信息可以由兩部分組成;header 和 body。在一個模塊化的應(yīng)用,當(dāng)消息發(fā)送出去時,這兩部分可以由不同的模塊生產(chǎn)和裝配。
<pre> +--------+----------+
| header | body |
+--------+----------+
</pre>
如果你使用的是 ByteBuffer ,你必須要創(chuàng)建一個新的大緩存區(qū)用來拷貝這兩部分到這個新緩存區(qū)中?;蛘?,你可以在 NiO做一個收集寫操作,但限制你將復(fù)合緩沖類型作為 ByteBuffer 的數(shù)組而不是一個單一的緩沖區(qū),打破了抽象,并且引入了復(fù)雜的狀態(tài)管理。此外,如果你不從 NIO channel 讀或?qū)懀菦]有用的。
// 復(fù)合類型與組件類型不兼容。
ByteBuffer[] message = new ByteBuffer[] { header, body };
通過對比, ByteBuf 不會有警告,因為它是完全可擴展并有一個內(nèi)置的復(fù)合緩沖區(qū)。
// 復(fù)合類型與組件類型是兼容的。
ByteBuf message = Unpooled.wrappedBuffer(header, body);
// 因此,你甚至可以通過混合復(fù)合類型與普通緩沖區(qū)來創(chuàng)建一個復(fù)合類型。
ByteBuf messageWithFooter = Unpooled.wrappedBuffer(message, footer);
// 由于復(fù)合類型仍是 ByteBuf,訪問其內(nèi)容很容易,
//并且訪問方法的行為就像是訪問一個單獨的緩沖區(qū),
//即使你想訪問的區(qū)域是跨多個組件。
//這里的無符號整數(shù)讀取位于 body 和 footer
messageWithFooter.getUnsignedInt(
messageWithFooter.readableBytes() - footer.readableBytes() - 1);
許多協(xié)議定義可變長度的消息,這意味著沒有辦法確定消息的長度,直到你構(gòu)建的消息?;蛘撸谟嬎汩L度的精確值時,帶來了困難和不便。這就像當(dāng)你建立一個字符串。你經(jīng)常估計得到的字符串的長度,讓 StringBuffer 擴大了其本身的需求。
// 一種新的動態(tài)緩沖區(qū)被創(chuàng)建。在內(nèi)部,實際緩沖區(qū)是被“懶”創(chuàng)建,從而避免潛在的浪費內(nèi)存空間。
ByteBuf b = Unpooled.buffer(4);
// 當(dāng)?shù)谝粋€執(zhí)行寫嘗試,內(nèi)部指定初始容量 4 的緩沖區(qū)被創(chuàng)建
b.writeByte('1');
b.writeByte('2');
b.writeByte('3');
b.writeByte('4');
// 當(dāng)寫入的字節(jié)數(shù)超過初始容量 4 時,
//內(nèi)部緩沖區(qū)自動分配具有較大的容量
b.writeByte('5');
最頻繁使用的緩沖區(qū) ByteBuf 的實現(xiàn)是一個非常薄的字節(jié)數(shù)組包裝器(比如,一個字節(jié))。與 ByteBuffer 不同,它沒有復(fù)雜的邊界和索引檢查補償,因此對于 JVM 優(yōu)化緩沖區(qū)的訪問更加簡單。更多復(fù)雜的緩沖區(qū)實現(xiàn)是用于拆分或者組合緩存,并且比 ByteBuffer 擁有更好的性能。
更多建議: