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. Windows PowerShell 终端配置

    如何修改 Windows PowerShell 的提示符 Windows PowerShell 支持配置文件,可以创建配置文件,通过配置文件来修改 配置文件路径 打开一个Windows Powersh ...

  2. Python · Jax | 在 python 3.8 上安装 jax,运行 offline RL 的 IQL

    致谢师兄的 jax 环境,完全按照师兄的 conda_env.yml 配置的 (如何导出其他环境的 conda_env.yml:Conda | 如何(在新服务器上)复制一份旧服务器的 conda 环境 ...

  3. java子类父类有相同的方法优先调用子类-重写-递归

    子类和父类有相同的方法,优先调用子类.如果子类没有,父类. package studyDemo9yue; public class study01 { public static void main( ...

  4. 一种面向混合云平台基于LSTM预测模型的资源池配额方法。

    本文分享自天翼云开发者社区<一种面向混合云平台基于LSTM预测模型的资源池配额方法.>,作者:l****n 基于用户的历史配额申请情况和实际资源使用情况组成数据集搭建LSTM时序预测模型. ...

  5. 一个登录功能也能玩出这么多花样?sa-token带你轻松搞定多地登录、单地登录、同端互斥登录

    需求场景 说起登录,你可能会不屑一顾,还有比这更简单的功能吗? 获取一下用户提交参数 username + password 和数据库中一比对,有记录返回[登录成功],无记录返回[用户名或密码错误] ...

  6. SqlServer性能检测之Sql语句排查

    很多时候,我们在用SQL语句查询数据时,难免会漏掉对SQL语句性能的考虑,所以有时就会造成SqlServer服务占用过高的问题,为了大致排查是哪些SQL语句造成的问题,我们可以通过如下SQL查询出最近 ...

  7. Amoro提供grafana的metrics介绍

    一.指标内容 +| Metric Name | Type | Tags | Description | +|---------------------------------------------- ...

  8. Thymeleaf判断集合是否为空

    Thymeleaf判断集合是否为空最近项目使用的是thymeleaf.项目架构是Springboot+Thymeleaf. 在判断集合是否为空的时候踩了坑与大家分享. 以下代码是判断集合是否为空的,m ...

  9. Failed to configure a DataSource: 'url' attribute is not specified and no embedded datasource could

    问题分析及解决方案 问题原因: Mybatis没有找到合适的加载类,其实是大部分spring - datasource - url没有加载成功,分析原因如下所示. DataSourceAutoConf ...

  10. Mybatis中的 switch

    我这遇到个问题,如果 type字段为null则查询type is null,否则查对应的值 询问 AI 得知,可以用choose-when-otherwise <select> selec ...