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参数值一致

相关内容

热门资讯

厨房里的湘味风暴:一道剁椒鱼头... 周末去菜市场,在水产档口前犹豫了五分钟,最后还是扛了个大花鲢鱼头回家。老板娘笑得眼睛眯成一条缝:"丫...
长江水融化昆仑雪:青海拉面小哥... 极目新闻记者 涂梦蝶 杨怡琴 摄影记者 刘中灿 通讯员 覃辰恺 王清江 冬日的清晨,天尚未大亮,积蓄...
域见上海 域见长宁|长宁秋日到... 上海动物园:上海动物园不仅是亲子家庭的天堂,更是一座充满故事的城市绿洲。在这里,你不仅能观赏到长颈鹿...
原创 绝... 在今年五一假期,一张名为大学生特种兵的照片引起了广泛的讨论。照片中的大学生人群密集,几乎把整个泰山围...
赤大师有机纯驼奶粉的价格,20... 赤大师有机纯驼奶粉的价格,2025年度央视十大靠谱驼奶粉!价格是否真实反映其科学营养配比? 大漠孤烟...