Direct Memory
一、直接内存
1.1定义
直接内存(Direct Memory):是一块操作系统中的内存,不受JVM管理,常用于NIO操作的数据缓冲
分配回收成本高(资源占用高),但是读写性能高(速度快)
1.2与传统内存比较
![](https://i-blog.csdnimg.cn/blog_migrate/ed7b9525f970e78ef66b6559dc321d42.png)
![](https://i-blog.csdnimg.cn/blog_migrate/7423b327929e262e7ce4e81d55b73de0.png)
解析:与传统内存模式不同的一点是,多出了一块直接内存缓存区,这块区域是Java内存和系统内存都可以直接调用,不用
像之前要复制到Java内存去运行
案例:NIO的 ByteBuffer类所用到的直接内存引用以及释放
public class test02_byteBufferDirectMemory {
static int _1Gb = 1024*1024*1024;
public static void main(String[] args) throws IOException {
ByteBuffer byteBuffer = ByteBuffer.allocateDirect(_1Gb);
System.out.println("分配完毕");
System.in.read();
System.out.println("开始释放");
byteBuffer = null;
System.gc();
System.in.read();
}
}
解析源码:
1.首先这个类的资源不会被GC所回收,因为它是属于直接内存区域,不涉及GC,
这个类真正释放资源的代码是一个叫做 unsafe对象的 freeMemory 方法
2.具体的实现在allocateDirect方法,进入之后会看到又调用了DirectByteBuffer类
3.进入DirectByteBuffer类后会看到 有unsafe对象出现了,并且核心代码是一个cleaner(虚引用)类,cleaner的create方法
会传入当前的DirectByteBuffer对象,以及一个回调方法
4.进入到回调方法,终于看到了要执行的 unsafe.freeMemory
5.接下来就是Cleaner类要做的,当释放资源时,ReferenceHandler线程(守护线程)会调用cleaner的clean方法,
然而在clean方法里,就看到了调用传入runnable接口对象的run方法,然后就去执行freeMemory了
![](https://i-blog.csdnimg.cn/blog_migrate/571180330ddf32dbcc189a2b519daf2f.png)