JVM -- 直接内存

并不属于JVM管理,属于系统内存,即操作系统的内存

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

传统的阻塞IO

使用直接内存

 观看耗时:

 说明直接内存远远快于传统的方式

原理 -- 为什么读写效率变高

java本身并不具备磁盘读写的能力,他要使用操作系统的方法,其实就是调用native方法 ,会涉及到用户态和内核态的切换,当切换到内核态,就可以由cpu的函数读取磁盘文件的内容,在操作系统内存划分出一块系统缓冲区,磁盘的内容存储到系统缓冲区,但是系统缓冲区Java代码是不能进行操作的,所以java也会在堆内存中分配一个java缓冲区,就是我们new的Byte数组,java要访问到系统缓冲区的数据,就要将系统缓冲区的内容读入到java缓冲区,因为现在有两块缓冲区,数据必然要存两份,造成不必要的浪费,效率不高

 

当调用ByteBuffer.allocateDirect()方法时,意味着会在操作系统中划分一块缓冲区,但是这块缓冲区不同的是,java系统可以访问到这块内存,那加入直接内存后,磁盘文件读取的时候,直接读取到直接内存,而java代码也可以读取到,少了一次数据的拷贝操作。 


内存溢出

既然直接内存不受jvm管理,会不会导致内存溢出呢

 执行代码,我们发现会有内存的溢出

 释放原理

我们执行程序,发现该程序占用了1G的内存 

 

我们发现置位null之后,内存占用变少,说明回收掉了

分配和回收原理

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

 禁用System.gc() ==> 显示的进行垃圾回收

触发的是FullGC,即也会回收老年代的垃圾

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值