直接内存了解学习

参考大佬链接

https://www.zhihu.com/question/284750570/answer/3526842569

内存结构篇:直接内存 - 小飞猪咯咯 - 博客园

黑马视屏普及截图

结合以上资料来学习直接内存,留下足迹。

一、直接内存定义

      直接内存(Direct Memory)并不是虚拟机运行时数据区的一部分,也不是《Java虚拟机规范》中定义的内存区域。但是这部分内存也被频繁地使用,而且也可能导致 OutOfMemoryError 异常出现。(即不属于JVM虚拟机内存区域,属于操作系统的内存)

      在 JDK1.4 中新引入了NIO类,它可以使用 Native 函数库直接分配堆外内存,然后通过 Java 堆里的 DirectByteBuffer 对象作为这块内存的引用进行操作。这样就能在一些场景中显著提高性能,因为避免了在 Java 堆(堆内存)和 Native 堆(堆外内存)中来回复制数据。

  • 常见于 NIO 操作时,用于数据缓冲区
  • 分配回收成本较高,但读写性能高
  • 不受 JVM 内存回收管理

二、直接内存优点缺点

     直接内存的优势在于没有堆内存到堆外内存的复制,直接使用堆外内存进行数据的传输。

以NIO文本拷贝和BIO文本拷贝图说明。

BIO 文件流读取文件流

普通FileInputStream 和FileOutputStream 来拷贝文件 缓存区在大小为1M

NIO 读取文件流

NIO channel 和 ByteBuffer.allocateDirect(1024) 分配1M的直接缓存区域 提高 I/O 操作性能减少内存拷贝

    Java NIO 提供了 ByteBuffer.allocateDirect() 方法来分配直接内存,它的优势在于它不会占用堆内存,而是直接与操作系统的内存进行交互。这可以减少内存拷贝的开销。

ByteBuffer directBuffer = ByteBuffer.allocateDirect(1024);

缺点:

  1. 内存泄漏风险:由于直接内存由操作系统管理而不是JVM管理,其分配和释放不受JVM的直接控制。若程序没有正确释放直接内存,就可能导致内存泄漏。

  2. 管理复杂性:直接内存的管理需要开发者显式地进行内存释放,增加了代码的复杂性。错误的内存管理可能导致程序崩溃或性能问题。

  3. 直接内存的分配和释放成本高,有一定的性能影响
  4. 内存抖动问题:虽然直接内存减少了垃圾收集的频率,但当直接内存使用量达到峰值时,可能会导致突然的内存不足。这种“内存抖动”会影响应用程序的稳定性。直接内存会被系统中其他程序影响,进而导致OOM

  5. 平台依赖性:直接内存的实现依赖于操作系统,因此在不同操作系统上可能表现不同。这增加了应用程序的测试和维护复杂性。

三、使用注意:

3.1 合理配置内存大小
      根据应用程序的需求合理配置直接内存大小。对于I/O密集型应用程序,可以适当增加直接内存的大小,以提高性能。使用-XX:MaxDirectMemorySize参数设置最大直接内存大小,并定期监控使用情况。

例如:

  • Java设置堆内存大小: -Xms=1G -Xmx=1G
  • 设置堆外内存:

-XX:MaxDirectMemorySize=1G

3.2 及时释放直接内存
     在使用直接内存时,确保及时释放内存以避免内存泄漏。可以使用ByteBuffer.clear()方法重用缓冲区,或在使用完成后调用Cleaner来显式释放内存。

3.3 监控直接内存使用
     JVM并没有内置的工具来直接监控直接内存的使用情况。但是,可以使用一些第三方工具或Java自带的诊断工具来间接监控。常用的方法包括:

JVisualVM:可以监控堆外内存的使用情况,包括直接内存。
Java NIO MBean:JVM中提供了一些MBean可以通过java.lang.management包访问到直接内存的使用信息。            

四、直接内存的用途


4.1 高性能I/O操作
      直接内存的最主要用途是在高性能I/O操作中。传统的Java I/O操作需要将数据从Java堆内存复制到操作系统的内核缓冲区,然后再传输到网络或文件。这种多次数据拷贝操作会导致性能瓶颈。通过使用直接内存,数据可以直接在操作系统的内核缓冲区中进行操作,从而减少数据拷贝,提高I/O操作的效率。

4.2 大数据处理
      在大数据处理和流处理系统中,如Netty、Kafka等框架,经常使用直接内存来提高数据传输的效率。直接内存允许这些框架处理大规模的数据而不受JVM堆内存大小的限制,减少了垃圾回收的频率,从而提高系统的吞吐量和性能。

4.3 零拷贝技术
      直接内存也是实现零拷贝技术的基础。在网络通信中,零拷贝允许数据直接从一个地方传输到另一个地方,而不需要经过CPU的拷贝操作。例如,从磁盘读取数据并直接发送到网络,而不需要经过用户态和内核态的多次拷贝。通过直接内存,Java可以更高效地实现零拷贝。

五 概括


      直接内存是Java虚拟机中一个重要的内存区域,通过java.nio包中的ByteBuffer类进行管理。直接内存的主要优点在于高效的I/O操作和降低JVM垃圾收集的负担,适用于高性能I/O和大数据处理的应用程序。然而,直接内存的管理也带来了新的挑战,如内存泄漏、平台依赖性和管理复杂性等。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值