JVM直接内存(Direct Memory)
创始人
2025-05-31 13:07:12

直接内存

1.直接内存不是虚拟机运行时数据区的一部分,也不是《Java虚拟机规范》中定义的内存区域。

2.直接内存是Java堆外的、直接向系统申请的内存区间。

3.简单理解: java process memory = java heap + native memory

示例代码:

/***  IO                  NIO (New IO / Non-Blocking IO)*  byte[] / char[]     Buffer*  Stream              Channel** 查看直接内存的占用与释放*/
public class BufferTest {private static final int BUFFER = 1024 * 1024 * 1024;//1GBpublic static void main(String[] args){//直接分配本地内存空间ByteBuffer byteBuffer = ByteBuffer.allocateDirect(BUFFER);System.out.println("直接内存分配完毕,请求指示!");Scanner scanner = new Scanner(System.in);scanner.next();System.out.println("直接内存开始释放!");byteBuffer = null;System.gc();scanner.next();}
}

直接内存来源于NIO

通过存在堆中的DirectByteBuffer操作Native内存。访问直接内存的速度会优于Java堆。即读写性能高。

  • 因此出于性能考虑,读写频繁的场合可能会考虑使用直接内存
  • Java的NIO库允许Java程序使用直接内存,用于数据缓冲区

直接内存异常OOM

同样,也可能导致OutOfMemoryError异常:OutOfMemoryError: Direct buffer memory

由于直接内存在Java堆外,因此它的大小不会直接受限于一Xmx指定的最大 堆大小,但是系统内存是有限的,Java堆和直接内存的总和依然受限于操作系统能给出的最大内存。

/*** 本地内存的OOM:  OutOfMemoryError: Direct buffer memory*/
public class BufferTest2 {private static final int BUFFER = 1024 * 1024 * 20;//20MBpublic static void main(String[] args) {ArrayList list = new ArrayList<>();int count = 0;try {while(true){ByteBuffer byteBuffer = ByteBuffer.allocateDirect(BUFFER);list.add(byteBuffer);count++;try {Thread.sleep(100);} catch (InterruptedException e) {e.printStackTrace();}}} finally {System.out.println(count);}}
}

直接内存参数设置

  • 使用直接内存的缺点
    • 分配回收成本较高
    • 不受JVM内存回收管理
  • 直接内存大小可以通过MaxDirectMemorySize设置
  • 如果不指定,默认与堆的最大值一Xmx参数值一致

相关内容

热门资讯

实测 2026 贵州包车游!贵... 为什么同样是报贵州定制小团游,有人全程舒心无忧,有人却深陷加价、缩水、推诿的泥潭?结合主流旅游平台投...
原创 海... 今年春节之时,来自海外的游客数量众多,将潮汕小巷挤得满满当当,还纷纷涌入黄山脚下,他们并非是想去观赏...
详释一下张家口酒吧街夜生活指南 # 张家口酒吧街夜生活指南 当夕阳的余晖渐渐隐没在张家口的群山之后,这座城市的另一面开始苏醒。位于市...
宝清县公园哪个最好人气高 宝清县的公园是当地居民休闲娱乐的好去处,每个公园都有其独特的魅力和特色。在众多公园中,究竟哪个公园人...
详谈一下嘉峪关酒吧街夜生活指南 # 嘉峪关酒吧街夜生活指南:戈壁明珠的不眠之夜 在中国西北的戈壁深处,嘉峪关这座古老关城不仅以长城西...