在Java NIO 中,ByteBuffer一般做爲通訊中傳遞消息的載體。而在Mina中,採用了IoBuffer代替ByteBuffer。Mina給出了不用ByteBuffer的兩個主要理由:app
1. ByteBuffer未提供一些經常使用到的get/set方法,如:fill, get/putString, get/putAsciiIntsocket
這裏附上,fill方法在AbstractIoBuffer中的實現,能夠看到程序分別採用Long,Int,Short,byte對指定size的byte內容進行了快速填充,而不是採用for循環,是個有趣的技巧。網站
public IoBuffer fill(byte value, int size) { autoExpand(size); int q = size >>> 3; int r = size & 7; if (q > 0) { int intValue = value | value << 8 | value << 16 | value << 24; long longValue = intValue; longValue <<= 32; longValue |= intValue; for (int i = q; i > 0; i--) { putLong(longValue); } } q = r >>> 2; r = r & 3; if (q > 0) { int intValue = value | value << 8 | value << 16 | value << 24; putInt(intValue); } q = r >> 1; r = r & 1; if (q > 0) { short shortValue = (short) (value | value << 8); putShort(shortValue); } if (r > 0) { put(value); } return this; }
2. ByteBuffer一旦分配,容量固定,不易擴展。this
在Mina的實現中,IoBuffer的擴展是經過從新分配一塊新的更大的ByteBuffer,並把舊的ByteBuffer拷貝到新的當中實現的,這種實現的問題顯而易見,可能致使頻繁分配內存,生成內存碎片。另外,在用戶使用DirectBuffer時,頻繁的內存分配和釋放(ByteBuffer.clear())可能致使內存不能及時回收,從而致使內存泄漏。關於IoBuffer自動擴展的問題在Mina的官方網站上也有說起:spa
This will change in MINA 3. The main reason why MINA has its own wrapper on top of nio ByteBuffer is to have extensible buffers. This was a very bad decision. Buffers are just buffers : a temporary place to store temporary data, before it is used. Many other solutions exist, like defining a wrapper which relies on a list of NIO ByteBuffers, instead of copying the existing buffer to a bigger one just because we want to extend the buffer capacity. It might also be more comfortable to use an InputStream instead of a byte buffer all along the filters, as it does not imply anything about the nature of the stored data : it can be a byte array, strings, messages... Last, not least, the current implementation defeat one of the target : zero-copy strategy (ie, once we have read the data from the socket, we want to avoid a copy being done later). As we use extensible byte buffers, we will most certainly copy those data if we have to manage big messages. Assuming that the MINA ByteBuffer is just a wrapper on top of NIO ByteBuffer, this can be a real problem when using direct buffers.
總結起來主要是:0. 實現自動擴展是錯誤的決定; 1. 能夠有更好的實現方式,如ByteBuffer List; 2. 違反了zero-copy 原則; 3. 在用戶使用Direct模式管理較大的Message存在內存泄漏的風險。code
可見Mina對於ByteBuffer的包裝IoBuffer是存在必定問題的,官方考慮放棄。可是Mina社區目前基本處於停滯狀態。(最新的穩定版本時間仍是2016年10月)blog