JVM之直接内存与非直接内存
直接内存
-
直接内存:概指系统内存,而非堆内存,不指定大小时它的大小默认与堆的最大值-Xmx参数值一致。
-
非直接内存: 也可以称之为堆内存,运行JVM都会预先分配一定内存,我们把JVM管理的这些内存称为堆内存(非操作系统直接内存),JVM会对这些内存空间的分配和回收进行管理。
所谓 直接的关系指的是与底层操作系统的关系。
直接 非直接内存的概念与NIO有非常大的关联;
-
在NIO之前,java.io 的方式是:
磁盘IO <读取> -读-> 直接内存[系统内核态] -读-> 非直接(堆)内存[用户态] -写-> 直接内存[系统内核态] -写-> 磁盘IO <写入磁盘>
-
而NIO中,对文件的读写不再跟堆内存关联
磁盘IO --> 系统直接内存 --> 磁盘IO
读写文件时可以直接申请堆外内存。
优点
-
避免内核态和用户态之间反复切换,实现文件的高效存取;
-
非JVM管理内存,能减少GC时造成的STW(stop the world)操作。
缺点
内存管理的成本增加,由于没有自动回收机制的管理,使用不当可能造成内存溢出。
直接内存的使用
我们知道直接内存直接使用操作系统内存,避免了反复的拷贝。
直接内存的使用通过:allocateDirect创建,需要注意的时,直接内存的申请成本比申请普通堆内存更大;
基于以上特性,直接内存在文件较大时会有不错的表现,由于申请开销问题,当操作海量的小文件时我们就需要慎重考虑是否使用直接内存了,此时还会带来内存碎片化的问题。