零拷貝
- 複製很大的文件
- 頻繁的IO操作,例如網絡併發場景
回收
- 自動回收
- GC 時會掃描 DirectByteBuffer 對象是否有有效引用指向該對象,如沒有,在回收 DirectByteBuffer 對象的同時且會回收其佔用的堆外內存
-
虛引用(Phantom Reference)
- 也稱爲幽靈引用或者幻影引用
- 一個對象是否有虛引用的存在,完全不會對其生存時間構成影響,也無法通過虛引用來取得一個對象實例。
- 爲一個對象設置虛引用關聯的唯一目的就是能在這個對象被收集器回收時收到一個系統通知
- GC過程中如果發現某個對象除了只有PhantomReference引用它之外,並沒有其他的地方引用它了,那將會把這個引用放到java.lang.ref.Reference.pending隊列裏,ReferenceHandler這個守護線程會處理pending隊列裏,執行一些後置處理,這裏是調用Cleaner的clean方法
- 而DirectByteBuffer構造方法內創建了一個Cleaner對象, Cleaner繼承了PhantomReference,其referent爲DirectByteBuffer,也是通過Cleaner調用unsafe.freeMemory(address)來釋放直接內存
-
手動回收
- DirectByteBuffer 實現了 DirectBuffer 接口,這個接口有 cleaner 方法可以獲取 cleaner 對象。
public static void clean(final ByteBuffer byteBuffer) { if (byteBuffer.isDirect()) { ((DirectBuffer)byteBuffer).cleaner().clean(); } }
- Netty 中的堆外內存池就是使用反射來實現手動回收方式進行回收的。