一,簡介
DirectByteBuffer是ByteBuffer關於堆外內存使用的實現,堆外內存直接使用unsafe方法請求堆外內存空間,讀寫數據,直接使用內存地址,效率非常的高
使用ByteBuffer提供的工廠類可獲得實例:
ByteBuffer sendBuf1 = ByteBuffer.allocateDirect(10);
1,常用類putInt
sendBuf1.putInt(1);
此方法使用4個字節保存int類型的數據
實現方法:
public ByteBuffer putInt(int x) { putInt(ix(nextPutIndex((1 << 2))), x); return this; }
nextPutIndex 寫入數據時通過position 計算下一個寫入的數據事第幾個
final int nextPutIndex(int nb) { // package-private if (limit - position < nb) throw new BufferOverflowException(); int p = position; position += nb; return p; }
ix 方法計算下一個數據寫入的內存地址
address 在創建實例時,申請內存地址后保存的,申請到內存地址的首地址address+position+1便是下一個可寫入地址
private long ix(int i) { return address + ((long)i << 0); }
unaligned :判斷系統架構
如果是以下架構便返回ture

nativeByteOrder :判斷系統儲存使用的是大端還是小端,如果系統是大端返回true

關於大端小端的詳細介紹:https://www.cnblogs.com/dybe/p/11790955.html
Bits.swap(y) :小端情況下,將int類型的字節順序反轉后得到的補碼值
unsafe.putInt(long a,int b)
unsafe提供的直接操作內存的方法,a:內存地址,b:要寫入的數據
Bits.putInt 自己實現數據字節翻轉保存
//a:寫入數據的內存地址
//x:要寫入的數據
private ByteBuffer putInt(long a, int x) { if (unaligned) { int y = (x); unsafe.putInt(a, (nativeByteOrder ? y : Bits.swap(y))); } else { Bits.putInt(a, x, bigEndian); } return this; }
2,getInt方法同理如果是小端,將數據取出后,進行字節反轉后再返回
private int getInt(long a) { if (unaligned) { int x = unsafe.getInt(a); return (nativeByteOrder ? x : Bits.swap(x)); } return Bits.getInt(a, bigEndian); }