一、直接内存概述
1、不是虚拟机运行时数据区的一部分,也不是《Java虚拟机规范》中定义的内存区域。
2、直接内存是在Java堆外的、直接向系统申请的内存区间;
3、来源于NIO,通过存在堆中的 DirectByteBuffer 操作 Native 内存;
4、通常,访问直接内存的速度会优于 Java 堆。即读写性能高;
因此出于性能考虑,读写频繁的场合可能会考虑使用直接内存;
Java的NIO库允许Java程序使用直接内存,用于数据缓冲区。
直接内存并不是虚拟机运行时数据区的一部分,也不是Java虚拟机规范中定义的内存区域,它直接从操作系统中分配,因此不受Java堆大小的限制,但是会受到本机总内存的大小及处理器寻址空间的限制,因此它也可能导致OutOfMemoryError异常出现。在JDK1.4中新引入了NIO机制,它是一种基于通道与缓冲区的新I/O方式,可以直接从操作系统中分配直接内存,即在堆外分配内存,这样能在一些场景中提高性能,因为避免了在Java堆和Native堆中来回复制数据。
二、访问直接内存的速度会优于 Java 堆
1、非直接缓冲区(传统IO)
读写文件,需要与磁盘交互,需要由用户态切换到内核态。在内核态时,需要内存如上图的操作。
使用IO,见上图。这里需要两份内存存储重复数据,效率低。
2、直接缓冲区(NIO)
使用NIO时,如上图。操作系统划出的直接缓存区可以被 java 代码直接访问,只有一份。NIO适合对大文件的读写操作。
因此出于性能考虑,读写频繁的场合可能会考虑使用直接内存;
代码示例:
1 public class BufferTest {
2 private static final int BUFFER = 1024 * 1024 * 1024;//1GB
3
4 public static void main(String[] args){
5 //直接分配本地内存空间
6 ByteBuffer byteBuffer = ByteBuffer.allocateDirect(BUFFER);
7 System.out.println("直接内存分配完毕,请求指示!");
8
9 Scanner scanner = new Scanner(System.in);
10 scanner.next();
11
12
13 System.out.println("直接内存开始释放!");
14 byteBuffer = null;
15 System.gc();
16 scanner.next();
17 }
18 }
三、直接内存的OOM与大小设置
1、也可能导致outofMemoryError异常(Direct buffer memory)
2、由于直接内存在Java堆外,因此它的大小不会直接受限于-Xmx 指定的最大堆大小,但是系统内存是有限的,Java堆和直接内存的总和依然受限于操作系统能给出的最大内存。
3、缺点
① 分配回收成本较高
② 不受 JVM 内存回收管理
4、直接内存大小可以通过MaxDirectMemorysize设置
5、如果不指定,默认与堆的最大值 -Xmx 参数值一致
设置本地内存:
1 本地内存的OOM: OutOfMemoryError: Direct buffer memory
2 public class BufferTest2 {
3 private static final int BUFFER = 1024 * 1024 * 20;//20MB
4
5 public static void main(String[] args) {
6 ArrayList<ByteBuffer> list = new ArrayList<>();
7
8 int count = 0;
9 try {
10 while(true){
11 ByteBuffer byteBuffer = ByteBuffer.allocateDirect(BUFFER);
12 list.add(byteBuffer);
13 count++;
14 try {
15 Thread.sleep(100);
16 } catch (InterruptedException e) {
17 e.printStackTrace();
18 }
19 }
20 } finally {
21 System.out.println(count);
22 }
23
24
25 }
26 }
简单理解:
Java process memory = java heap + native memory
更多:
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】凌霞软件回馈社区,博客园 & 1Panel & Halo 联合会员上线
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】博客园社区专享云产品让利特惠,阿里云新客6.5折上折
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 没有源码,如何修改代码逻辑?
· 一个奇形怪状的面试题:Bean中的CHM要不要加volatile?
· [.NET]调用本地 Deepseek 模型
· 一个费力不讨好的项目,让我损失了近一半的绩效!
· .NET Core 托管堆内存泄露/CPU异常的常见思路
· 微软正式发布.NET 10 Preview 1:开启下一代开发框架新篇章
· C# 集成 DeepSeek 模型实现 AI 私有化(本地部署与 API 调用教程)
· DeepSeek R1 简明指南:架构、训练、本地部署及硬件要求
· 没有源码,如何修改代码逻辑?
· NetPad:一个.NET开源、跨平台的C#编辑器