展会网站制作,企业装修展厅公司,网站建设培训学校,有没有好网站推荐JVM基础篇-直接内存
什么是直接内存?
直接内存( 堆外内存 ) 指的是 Java 应用程序通过直接方式从操作系统中申请的内存,这块内存不属于jvm
传统方式读取文件 首先会从用户态切换到内核态#xff0c;调用操作系统函数从磁盘读取文件#xff0c;读取一部分到操作系统缓冲区…JVM基础篇-直接内存
什么是直接内存?
直接内存( 堆外内存 ) 指的是 Java 应用程序通过直接方式从操作系统中申请的内存,这块内存不属于jvm
传统方式读取文件 首先会从用户态切换到内核态调用操作系统函数从磁盘读取文件读取一部分到操作系统缓冲区中然后从内核态切换到用户态从系统缓冲区复制数据到Java堆缓冲区中
利用直接内存读取文件 首先会从用户态切换到内核态调用操作系统函数从磁盘读取文件读取一部分到直接内存中java可以直接访问直接内存而不用进行再次复制从而效率得到成倍提升
直接内存溢出 直接内存也会出现内存溢出所以使用时需要小心
探究ByteBuffer
演示Unsafe对象的使用
/*** apiNote 直接内存是通过Unsafe对象的freeMemory方法完成内存释放而不是通过JVM自动垃圾回收*/
public class Demo10 {static int _1GB 1024 * 1024 * 1024;public static void main(String[] args) throws Exception {Unsafe unsafe getUnsafe();long base unsafe.allocateMemory(_1GB);//分配直接内存返回内存地址unsafe.setMemory(base, _1GB, (byte) 0);System.in.read();unsafe.freeMemory(base);//释放内存System.in.read();}public static Unsafe getUnsafe() {try {Field f Unsafe.class.getDeclaredField(theUnsafe);f.setAccessible(true);Unsafe unsafe (Unsafe) f.get(null);return unsafe;} catch (NoSuchFieldException | IllegalAccessException e) {throw new RuntimeException(e);}}
}ByteBuffer是怎么声明直接内存和回收内存的呢? 可以看出底层声明内存采用Unsafe对象声明而垃圾回收交给Cleaner对象进行管理 当虚ByteBuffer对象被回收时会自动触发任务的run方法该run方法会自动调用Unsafe对象的释放内存方法 当jvm设置为禁用显式的垃圾回收时直接内存只有到下次真正的垃圾回收时才会被释放需要解决这个问题可以通过Unsafe对象手动回收这部分内存
-XX:DisableExplicitGC //禁用显式的垃圾回收 相当于禁用System.gc()总结
使用了 Unsafe 对象完成直接内存的分配回收并且回收需要主动调用 freeMemory 方法ByteBuffer 的实现类内部使用了 Cleaner 虚引用来监测 ByteBuffer 对象一旦ByteBuffer 对象被垃圾回收那么就会由 ReferenceHandler 线程通过 Cleaner 的 clean 方法调用 freeMemory 来释放直接内存