JAVA直接内存(堆外内存)

版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/y3over/article/details/88791958

   不管是文件IO还是网络IO都是 操作系统管理的,他不认识JAVA堆,如果可让JAVA使用两方案:

        1.JVM把数据复制到JAVA堆中。

        2.作为内存映射,在JAVA堆是开出一假空间,映射到真实数据内存。  

    这两种方案分别对应着BIO,NIO。   

    直接内存并不是虚拟机运行时数据区的一部分,也不是Java 虚拟机规范中定义的内存区域。在JDK1.4 中新加入了NIO(New Input/Output)类,引入了一种基于通道(Channel)与缓冲区(Buffer)的I/O 方式,它可以使用native 函数库直接分配堆外内存,然后通过一个存储在Java堆中的DirectByteBuffer 对象作为这块内存的引用进行操作。这样能在一些场景中显著提高性能,因为避免了在Java堆和Native堆中来回复制数据。

   JAVA通过调用ByteBuffer.allocateDirect及 MappedByteBuffer 来进行内存分配。不过JVM对Direct Memory可申请的大小也有限制,可用-XX:MaxDirectMemorySize=1M设置,这部分内存不受JVM垃圾回收管理。

堆外内存的回收及虚引用

JAVA对象引用》叫告诉了我们有ReferenceQueue引用监视器。

当一个 DirectByteBuffer初始化的时候,都会创建cleaner对象( 继承PhantomReference)并把 其注册进ReferenceQueue中。

当DirectByteBuffer=null的时候,如果引用在放入PhantomReference过程中,JVM就会调用cleaner.clean 并放弃通知ReferenceQueue。

不过很多线上环境的JVM参数有-XX:+DisableExplicitGC,导致了System.gc()等于一个空函数,根本不会触发FGC

猜你喜欢

转载自blog.csdn.net/y3over/article/details/88791958
今日推荐