Java 中的直接内存(堆外内存)

在 Java 中,直接内存(Direct Memory)指的是不受 JVM 堆管理的内存区域,也称为堆外内存。直接内存的使用通常与 Java NIO(New I/O)相关,尤其是通过 ByteBuffer.allocateDirect() 方法分配的内存。

1. 直接内存的特点

  • 不在堆中:直接内存不属于 JVM 堆内存,也不受垃圾回收器管理。它通过操作系统直接分配,通常用于优化 I/O 操作。
  • 与操作系统内存交互:直接内存通常通过操作系统的底层 API 进行分配和管理,可以提供更高效的数据操作,尤其是用于高性能的 I/O 操作,如文件读取、网络通信等。

2. 直接内存的分配

  • ByteBuffer.allocateDirect():Java NIO 提供了 ByteBuffer.allocateDirect() 方法来分配直接内存,它的优势在于它不会占用堆内存,而是直接与操作系统的内存进行交互。这可以减少内存拷贝的开销。
ByteBuffer directBuffer = ByteBuffer.allocateDirect(1024);
  • 直接内存的管理:直接内存的分配是由操作系统和 JVM 共同管理的。当需要使用直接内存时,JVM 会通过操作系统的本地内存分配 API(如 mmap)来分配内存。而当直接内存不再使用时,JVM 会通过 sun.misc.Cleaner 来清理直接内存(如果不是通过 GC 管理的话)。

3. 直接内存的优缺点

优点:

  1. 高性能:直接内存可以避免堆内存和操作系统内存之间的拷贝,减少了内存操作的开销,尤其是在高性能的 I/O 操作中,如网络通信、大文件的读取/写入等。
  2. 减少 GC 压力:直接内存不在堆中,因此不会被垃圾回收器管理,减少了 GC 的负担,减少了频繁的垃圾回收对性能的影响。
  3. 与操作系统内存交互:直接内存直接与操作系统的内存进行交互,通常用于需要频繁进行大数据量传输的场景,能提高内存访问效率。

缺点:

  1. 内存管理复杂:直接内存不受 JVM 的垃圾回收管理,需要开发者手动进行清理,容易出现内存泄漏问题,增加了内存管理的复杂性。
  2. 分配开销大:直接内存的分配通常比堆内存更为复杂,涉及到操作系统的调用,性能上比堆内存稍差。对于频繁的小对象分配,可能会引入不必要的开销。
  3. 有限的大小:直接内存的总量通常受到操作系统和硬件的限制,因此需要根据操作系统的可用内存进行合理的配置,过多的直接内存分配可能导致系统内存不足。
  4. 平台依赖性:由于直接内存涉及操作系统的底层 API(如 mmap),因此其实现是平台依赖的,不同操作系统的实现细节可能会有所不同。

4. 直接内存的使用场景

  1. 高性能 I/O:例如,NIO 的 ByteBuffer,尤其是在文件 I/O、大数据传输等需要频繁读写大数据量的场景中使用直接内存。
  2. 大数据处理:需要大量存储和高速处理数据时,直接内存能够提供更高效的访问和操作。
  3. 内存映射文件:使用 MappedByteBuffer 将文件内容直接映射到内存中,直接操作内存可以加速文件的读取和写入。

5. 内存溢出

直接内存如果使用不当,可能导致 OutOfMemoryError,错误信息如下:

java.lang.OutOfMemoryError: Direct buffer memory

总结

  1. 直接内存:即堆外内存,不属于 JVM 堆的一部分,由操作系统和 JVM 共同管理。它主要用于提高 I/O 操作性能,减少内存拷贝和 GC 压力。
  2. 分配方式:通过 ByteBuffer.allocateDirect() 等方法进行分配,直接内存的管理和释放需要开发者注意。
  3. 优缺点:虽然具有高性能,但内存管理较为复杂,容易造成内存泄漏。

什么是 Java 中的直接内存(堆外内存)?的更多相关文章

  1. cassandra 堆外内存管理

    为什么需要堆外内存呢 单有一些大内存对象的时候,JVM进行垃圾回收时需要收集所有的这些对象的内存也.增加了GC压力.因此需要使用堆外内存. java 分配堆外内存 org.apache.cassand ...

  2. Java堆外内存的使用

    堆外内存的回收见HeapByteBuffer和DirectByteBuffer以及回收DirectByteBuffer 基本类型长度 在Java中有很多的基本类型,比如: byte,一个字节是8位bi ...

  3. Netty之Java堆外内存扫盲贴

    Java的堆外内存本来是高贵而神秘的东西,只在一些缓存方案的收费企业版里出现.但自从用了Netty,就变成了天天打交道的事情,毕竟堆外内存能减少IO时的内存复制,不需要堆内存Buffer拷贝一份到直接 ...

  4. Java中的成员初始化顺序和内存分配过程

    Java中的成员初始化顺序和内存分配过程 原帖是这样描述的: http://java.dzone.com/articles/java-object-initialization?utm_source= ...

  5. Java 堆外内存

    入口ByteBuffer.allocateDirect public static ByteBuffer allocateDirect(int capacity) { return new Direc ...

  6. 浅谈Java中的栈和堆

    人们常说堆栈堆栈,堆和栈是内存中两处不一样的地方,什么样的数据存在栈,又是什么样的数据存在堆中? 这里浅谈Java中的栈和堆 首先,将结论写在前面,后面再用例子加以验证. Java的栈中存储以下类型数 ...

  7. Java堆外内存之突破JVM枷锁

    对于有Java开发经验的朋友都知道,Java中不需要手动的申请和释放内存,JVM会自动进行垃圾回收:而使用的内存是由JVM控制的. 那么,什么时机会进行垃圾回收,如何避免过度频繁的垃圾回收?如果JVM ...

  8. Java堆外内存管理

    Java堆外内存管理   1.JVM可以使用的内存分外2种:堆内存和堆外内存: 堆内存完全由JVM负责分配和释放,如果程序没有缺陷代码导致内存泄露,那么就不会遇到java.lang.OutOfMemo ...

  9. Java堆外内存之五:堆外内存管理类ByteBuffer

    本篇主要讲解如何使用直接内存(堆外内存),并按照下面的步骤进行说明: 相关背景-->读写操作-->关键属性-->读写实践-->扩展-->参考说明 希望对想使用直接内存的朋 ...

  10. Java堆外内存之四:直接使用Unsafe类操作堆外内存

    在nio以前,是没有光明正大的做法的,有一个work around的办法是直接访问Unsafe类.如果你使用Eclipse,默认是不允许访问sun.misc下面的类的,你需要稍微修改一下,给Type ...

随机推荐

  1. LVGL图形库

    一.LVGL实现思想 LVGL以结构体的形式来实现类 父子对象的关系 1.子对象会随着父对象移动 2.子对象超出父对象范围的部分不显示 二.基础对象部件 基础对象lv_obj可以作为父对象来创建其它对 ...

  2. 恭喜我同事的论文被IEEE HPCC收录!

    近日,由天翼云科技有限公司云网产品事业部天玑实验室撰写的<关于公有云区分负载QoS感知的内存资源动态超分管理优化>(Thoth:Provisioning Overcommitted Mem ...

  3. 多云时代!天翼云TeleDB以科技创新释放数据价值

    8月17日,在第14届中国数据库技术大会(DTCC2023)上,天翼云科技有限公司数据库首席技术官李跃森以<天翼云TeleDB持续创新之路>为题发表演讲,介绍了天翼云TeleDB数据库的发 ...

  4. LeetCode 第2题:两数相加

    LeetCode 第2题:两数相加 题目描述 给你两个 非空 的链表,表示两个非负的整数.它们每位数字都是按照 逆序 的方式存储的,并且每个节点只能存储 一位 数字. 请你将两个数相加,并以相同形式返 ...

  5. vue-element-template去除登录

    一.修改src目录下的permission.js文件 1.注释 //if (hasToken) { // if (to.path === '/login') { // // if is logged ...

  6. [虚拟化/Docker] Docker Desktop 安装与使用

    0 序:DeepSeek 等AI大模型在Windows的私有化部署 DeepSeek 等AI大模型在Windows的私有化部署,最流行的开源AI终端应用----Dify,依赖于 Docker 环境.由 ...

  7. 每次下载idea都必装的十个插件!

    IDEA必备插件 Alibaba Java Coding Guidelines 功能: 阿里巴巴Java开发规范插件,用于代码规范检查. 特点: 基于阿里巴巴Java开发手册,提供实时代码规范检查,帮 ...

  8. Windows下快捷方式 (*.lnk) 的使用技巧整理

    日常应用中,许多软件都会在安装过程最后一步添加多个命令,针对其应用创建快捷方式发送到桌面以及快速启动栏和开始菜单,供人们快速找到并打开.在我的使用习惯中也会将诸多常用的应用右键-发送到-桌面快捷方式来 ...

  9. win32绘图:绘制直线 矩形 圆形 曲线等

    查看代码 #include <Windows.h> //画点 void PaintSetPixel(HDC hdc) { for (short i = 0; i < 20; i++) ...

  10. 音视频SDK对比|K歌App中的实时合唱功能如何进行技术选型

    摘要 在线K歌软件的开发有许多技术难点,需考虑到音频录制和处理.实时音频传输和同步.音频压缩和解压缩.设备兼容性问题等技术难点外,此外,开发者还应关注音乐版权问题,确保开发的应用合规合法. 前言 前面 ...