Mina IoBuffer的特性介紹
一個位元組緩衝區被Mina的應用程式所使用。這是一個ByteBuffer的替代類。Mina不直接使用NIOByteBuffer,有兩個原因:
- 它不提供有用的getters和putters方法,如fill/ putString,get/ putAsciiInt()。
- 由於其固定容量很難寫變長資料.
這將在Mina3改變。Mina有自己的包裝主要原因是拓展nio ByteBuffer實現可擴充套件的緩衝區。這是一個非常糟糕的決定。緩衝區緩衝:臨時儲存臨時資料,之前使用它。存在許多其他的解決方案,比如定義一個包裝器,依靠NIO
bytebuffer的列表,而不是複製現有的緩衝區更大的一個僅僅因為我們希望延長緩衝能力。
它也可能是更舒適使用InputStream而不是一個位元組緩衝區的過濾器,因為它並不意味著對儲存資料的性質:它可以是一個位元組陣列,字串,訊息……
最後,同樣重要的是,當前實現失敗的一個目標:零拷貝策略(例如,一旦我們從套接字讀取資料,稍後我們不想做一個副本)。我們使用可擴充套件位元組緩衝區,我們將肯定複製這些資料如果我們有處理大訊息。假設Mina的ByteBuffer只是一個包裝器NIO ByteBuffer之上,在使用直接緩衝區時這可能是一個真正的問題。
1.1.1. IoBuffer操作
1.1.1.1. 分配一個新的緩衝區
IoBuffer是一個抽象類,因此不能直接例項化。分配
<span style="font-size:12px;">// Allocates a new buffer with a specific size, defining its type (direct or heap) public static IoBuffer allocate(int capacity, boolean direct) // Allocates a new buffer with a specific size public static IoBuffer allocate(int capacity)</span>
allocate()方法接受一個或兩個引數。第一個結構需要兩個引數:
· capacity - 緩衝區的容量大小
· direct - 型別的緩衝區。true直接使用緩衝區,false使用堆緩衝區
另外,還可以使用以下形式:
<span style="font-size:12px;">// Allocates heap buffer by default.
IoBuffer.setUseDirectBuffer(false);
// A new heap buffer is returned.
IoBuffer buf = IoBuffer.allocate(1024);</span>
使用第二種形式時,別忘了之前設定預設緩衝型別,否則您將得到預設堆緩衝區。
1.1.2. 建立自動擴充套件的緩衝區
建立自動擴大緩衝與java NIO API不是很容易,因為固定大小的緩衝區。有一個緩衝區,可以自動擴充套件需要的是網路應用的一大亮點。為了解決這個問題,IoBuffer引入了autoExpand屬性。它會自動擴大容量和極限值。
讓我們看看如何建立一個自動擴大緩衝區:
<span style="font-size:12px;">IoBuffer buffer = IoBuffer.allocate(8);
buffer.setAutoExpand(true);
buffer.putString("12345678", encoder);
// Add more to this buffer
buffer.put((byte)10);</span>
底層ByteBuffer在幕後重新分配是IoBuffer。如果編碼資料大於8個位元組在上面的例子中。容量大小將翻倍,其限制將增加到最後位置的字串。這種行為非常類似於StringBuffer類的工作方式。
這種機制很可能是遠離Mina3.0,因為它不是最好的方式來處理增加的緩衝區大小。取而代之的應該是類似InputStream隱藏列表或一個固定大小的bytebuffer)陣列。
1.1.3. 建立自動收縮的緩衝區
有些情況下,呼叫釋放另外分配的位元組緩衝區以儲存到記憶體。IoBuffer提供autoShrink屬性處理的需要。如果autoShrink開啟,IoBuffer半緊湊時緩衝區的容量()呼叫,只有1/4或少使用當前的能力。手動收縮緩衝區,使用shrink()方法。
讓我們看看這種方式:
<span style="font-size:12px;">IoBuffer buffer = IoBuffer.allocate(16);
buffer.setAutoShrink(true);
buffer.put((byte)1);
System.out.println("Initial Buffer capacity = "+buffer.capacity());
buffer.shrink();
System.out.println("Initial Buffer capacity after shrink = "+buffer.capacity());
buffer.capacity(32);
System.out.println("Buffer capacity after incrementing capacity to 32 = "+buffer.capacity());
buffer.shrink();
System.out.println("Buffer capacity after shrink= "+buffer.capacity());</span>
我們最初分配一個容量為16,autoShrink屬性設定為true。
我們來看它的輸出:
<span style="font-size:12px;">Initial Buffer capacity = 16
Initial Buffer capacity after shrink = 16
Buffer capacity after incrementing capacity to 32 = 32
Buffer capacity after shrink= 16</span>
讓我們休息一下和分析輸出:
- 初始緩衝容量是16,我們建立的緩衝能力。內部這變成了最低的緩衝能力
- 呼叫後shrink(),能力仍然是16,能力永遠不會小於最小能力
- 增加32的能力後,變成了32的能力
- shrink()的呼叫,減少能力16,從而消除額外的儲存
同樣,這種應該是一個預設機制,無需影響告訴緩衝,它可以縮小。
1.1.4. 緩衝區分配
IoBufferAllocater負責分配和管理緩衝區。精確控制緩衝區分配策略,實現IoBufferAllocater介面。
Mina附帶IoBufferAllocater的實現:
- SimpleBufferAllocator(預設),每次都建立一個新的緩衝區
- CachedBufferAllocator——快取緩衝區可能被重用擴張
在新的可用的JVM中,使用快取IoBuffer很可能提高效能。
您可以實現您自己的實現IoBufferAllocator並呼叫setAllocator()在IoBuffer使用相同。