直接内存

直接内存是操作系统内存;不属于JVM部分

直接内存定义

  • 常见于NIO操作时,用于数据缓冲区
  • 分配回收成本较高,但读写性能高
  • 不受JVM内存回收管理

直接内存的基本使用

使用 io 函数进行读写文件后:

用时大约2921,过程:磁盘文件首先进入到系统缓冲区,但是系统缓冲区中Java的代码是不可以运行的,所以Java堆缓冲区中会划分一块Java缓冲区,然后再将Java堆缓冲区再去访问系统缓冲区中的内容,这就出现一个问题,因为有两块缓冲区,所以,第一次在系统缓冲区中还不行,因为Java访问不到,所以要复制一份给Java缓冲区,这就造成了不必要数据的复制;

使用 directBuffer 函数后,运行速度明显变快了;

用时大约892,过程:会在操作系统中划分出一块内存directBuffer,这块内存系统内存可以访问,Java堆内存也可以访问,这就是直接内存,这比刚刚少了复制的操作,这样速度也会得到很大的提升;

直接内存的出现,使得Java代码和系统内存都可以进行访问,省去了第一张图中分别开辟两块缓冲区内存,如此速度得到了提升;直接内存比较适合做文件的操作;

例题:演示直接内存溢出

输出36,提示信息:java.lang.outOfMemoryError: Direct buffer memory   

直接内存的释放原理

例题:演示直接内存释放

这里查看内存大小不能使用前面的JVM工具,要使用任务管理器进行查看;

运行之后发现结果和上一张图一致,说明直接内存的内存释放,并不是通过垃圾回收器进行回收的,而是通过 unsafe 进行回收的;Java中的垃圾回收不需要我们去手动释放内存,它会自动释放内存,但是在直接内存中,它不会自动释放内存,需要手动调用 unsafe 中的 freeMemory 方法进行内存释放;

总结:分配和回收原理

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

禁用显式回收对直接内存的影响

因为此时不能进行垃圾回收,只能借助直接内存来释放内存;

 

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值