ByteBuffer原理与unsafe类以及关于jvm 和 系统之间的直接内存

传统io 流拷贝文件的原理

java 本身不具备磁盘读写能力 需要调用操作系统提供的函数 System  当切换系统函数时 CPU才会去磁盘读取文件,然后会在操作系统内存中画出一块 系统缓冲区 然后将文件内容分次读取到系统缓冲区,java 不能直接读取系统缓存区 ,所以java 会在堆内存中 分配出一个 java缓冲区,然后在间接的将系统缓存区的数据读取到java缓冲区,最后调用java的 写入操作,最终反复读写,到最后文件复制到目标地址

缺点  因为需要分配2个缓冲区 来造成不必要的复制 造成效率低下

使用NIO流

它会在 系统内存 之间 画出一个 缓冲区即直接内存  ,java可以访问到这个 直接内存,所以cpu会将文件 读取到这个直接内存 ,而java 也可以读取这个直接内存  进行文件复制,也就是比传统io流少了一次缓冲区文件复制操作 所以效果成倍提升了

如何分配直接内存 

我们可以使用 jdk 自带的 Nio 包下的ByteBuffer 来操作 

分配直接内存 和释放直接内存底层 调用的方法

unsafe里的 allocateMenory 方法  进行直接内存分配    

unsafe里的 freeMemory方法 进行释放直接内存

ByteBuffer 分配内存和释放内存原理

我们来看下 这个ByteBuffter里的 allocateDirect方法

 其调用了 DirectByteBuffer 构造器 

我们可以看到 DirectByteBuffter 构造方法里 面调用  unsafe里的 allocateMenory 方法  进行直接内存分配    

 

 这里 this 是指当前对象 如果当前对象被回收 则触发 虚引用对象 Cleaner 对象里的 clean 方法   进而 直接调用 传入构造注入的 new Deallocator(这个Deallocator 实现了 Runnable接口)  里的run方法   这个run方法里面 会调用 unsafe里的 freeMemory方法 从而直接释放直接内存

简单总结

使用了 Unsafe 对象完成直接内存的分配回收,并且回收需要主动调用 freeMemory 方法
分配是用  allocateMenory 方法
回收是用  freeMemory 方法
ByteBuffffer 的实现类内部,使用了 Cleaner (虚引用)来监测 ByteBuffffer 对象,一旦
ByteBuffffer 对象被垃圾回收,那么就会由 ReferenceHandler 线程通过 Cleaner 的 clean 方法调
用 freeMemory 来释放直接内存

  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值