零拷贝
- 复制很大的文件
- 频繁的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 中的堆外内存池就是使用反射来实现手动回收方式进行回收的。