【从零开始学习JVM | 第六篇】快速了解 直接内存

news2024/9/20 9:36:21

前言:

当谈及Java虚拟机(JVM)的内存管理时,我们通常会想到堆内存和栈内存。然而,还有一种被称为"直接内存"的特殊内存区域,它在Java应用程序中起着重要的作用。直接内存提供了一种与Java堆内存和本地内存进行交互的方式,同时也为我们提供了更高效的内存管理手段。

在本文中,我们将深入探讨JVM直接内存的概念、工作原理和使用场景。我们将介绍直接内存与Java堆内存的对比,探讨其中的异同点。此外,我们还将探讨如何使用Java NIO库来操作直接内存,以及如何通过合理的使用直接内存来提升应用程序的性能。

目录

前言:

直接内存:

直接内存的优点:

 如何操作直接内存:

JAVA代码方式:

 手动设置方式:

JVM使用场景:

总结:


直接内存:

        在Java虚拟机(JVM)中,直接内存(Direct Memory) 是一块与Java堆独立管理的内存区域。它是通过Java NIO(New I/O)库引入的一种特性。与Java堆相比,直接内存的分配和释放不受Java堆大小限制,因此可以在一些特定场景下提供更高的性能。        

直接内存 在《Java虚拟机规范》中并不存在,所以不属于Java运行时的内存区域。

直接内存提升了IO操作的效率,在传统的IO操作中,我们的执行流程是这样的:

 本地文件先要读取到内存当中,然后再复制到Java堆中,才可以进行读操作。

而如果我们使用直接内存,就不需要再去将数据复制到Java堆中才可以进行读操作,而是在堆中创建一个Java对象的引用。

通过这种方式减少了数据复制的开销,提高了效率。

直接内存的优点:

  1. 无需垃圾回收:直接内存并不受Java堆的垃圾回收机制管理,不会占用宝贵的堆空间,也不会对垃圾回收器产生额外的压力。
  2. 与本地操作系统直接交互:直接内存是通过使用本地方法库(Native Libraries)来与操作系统进行交互的。这意味着可以利用操作系统提供的高效的内存管理功能,如零拷贝等。
  3. 基于操作系统的零拷贝:在使用直接内存进行I/O操作时,可以通过零拷贝技术将数据直接从直接内存传输到网络或磁盘上,避免了数据复制的开销,提高了性能。
  4. 分配和释放成本较高:由于直接内存需要与操作系统进行交互,所以它的分配和释放成本相对较高,而且需要谨慎管理以避免资源泄漏。

 如何操作直接内存:

JAVA代码方式:

        在Java中,可以使用  java.nio.ByteBuffer  类来创建直接内存数据。直接内存是通过操作系统分配的内存,不受 Java 堆内存大小的限制,通常用于需要频繁 I/O 操作的场景。

import java.nio.ByteBuffer;

public class DirectMemoryExample {
    public static void main(String[] args) {
        // 分配直接内存,创建一个容量为 10 字节的 ByteBuffer
        ByteBuffer directBuffer = ByteBuffer.allocateDirect(10);

        // 在直接内存中写入数据
        for (int i = 0; i < 10; i++) {
            directBuffer.put((byte) i);
        }

        // 读取直接内存中的数据
        directBuffer.flip();
        while (directBuffer.hasRemaining()) {
            System.out.print(directBuffer.get() + " ");
        }

        // 释放直接内存,显式调用释放方法
        clean(directBuffer);
    }

    // 释放直接内存的方法
    public static void clean(final ByteBuffer buffer) {
        if (buffer.isDirect()) {
            try {
                sun.misc.Cleaner cleaner = ((sun.nio.ch.DirectBuffer) buffer).cleaner();
                if (cleaner != null) {
                    cleaner.clean();
                }
            } catch (Exception e) {
                e.printStackTrace();
            }
        }
    }
}

 手动设置方式:

可以通过 -XX:MaxDirectMemorySize  JVM 参数来手动设置直接内存的最大值。该参数用于限制直接内存的大小,当超出该值时,会抛出OutOfMemoryError异常。

下面是一个示例的 JVM 启动参数:

java -XX:MaxDirectMemorySize=1g MyApplication

这个命令会将直接内存的最大值设置为 1GB,并启动 MyApplication  应用程序。

需要注意的是   -XX:MaxDirectMemorySize   参数只是用于限制直接内存的大小,并不代表实际分配的直接内存大小。例如,如果分配的直接内存大小超过了该参数所设置的上限,也不会立即抛出异常,而是视情况在发生 GC 或者其他操作时释放部分直接内存。因此,在使用直接内存时,需要根据实际情况合理设置该参数的值,避免过度占用系统资源。

JVM使用场景:

  1. 网络编程:在网络通信中,需要频繁地进行数据的读取和发送,如果使用堆内存,就需要将数据先读入堆内存,再复制到网络缓冲区中,这样会增加不必要的开销。使用直接内存,可以直接将数据映射到网络缓冲区,避免数据复制,提高了网络通信的效率。

  2. 文件操作:在读写大文件时,使用传统的文件读写方式,需要将数据先读入堆内存,再进行处理。使用直接内存,可以直接将文件映射到内存中,避免了数据复制,减少了 I/O 操作的次数,提高了文件读写的效率。

  3. 图像处理和多媒体应用:在图像处理和多媒体应用中,需要频繁地进行像素数据的读取和处理。使用直接内存,可以将像素数据映射到内存中,避免了数据复制,提高了图像处理和多媒体应用的效率。

需要注意的是,使用直接内存时需要特别谨慎,因为直接内存是由操作系统分配的,不受 JVM 垃圾回收机制的管理,如果分配过多的直接内存,可能会导致操作系统资源耗尽,从而影响系统的稳定性。因此,在使用直接内存时,需要根据实际情况合理设置直接内存的大小,并在使用完毕后及时释放直接内存。

总结:

        总的来说,JVM 直接内存在现代 Java 应用程序中扮演着重要的角色。它主要用于提高 I/O 操作的效率,特别是在涉及网络通信、文件操作和大规模数据处理时。通过直接内存,可以避免数据的额外复制,直接在操作系统级别操作数据,从而提高了应用程序的性能和吞吐量。

然而,使用直接内存也需要谨慎对待。由于直接内存不受 JVM 垃圾回收机制管理,过度使用可能导致操作系统资源耗尽,影响系统的稳定性。因此,在使用直接内存时,需要合理设置直接内存的大小,并确保及时释放不再需要的直接内存,以避免潜在的问题。

综上所述,合理利用 JVM 直接内存可以有效提升 Java 应用程序的性能,但同时也需要注意资源管理和释放,以确保系统的稳定性和可靠性。

如果我的内容对你有帮助,请点赞,评论,收藏。创作不易,大家的支持就是我坚持下去的动力!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1305311.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

DRBD分布式存储实验

DRBD DRBD的全称为&#xff1a;Distributed Replicated Block Device (DRBD) 分布式块设备复制 与心跳连接结合使用&#xff0c;构建高可用性(HA)的集群。 实现方式是通过网络来镜像(mirror)整个设备。它允许用户在远程机器上建立一个本地块设备的实时镜像。DRBD负责接收数据…

[Linux] Tomcat

一、Tomcat相关知识 1.1 Tomcat的简介 Tomcat 是 Java 语言开发的&#xff0c;Tomcat 服务器是一个免费的开放源代码的 Web 应用服务器&#xff0c;是 Apache 软件基金会的 Jakarta 项目中的一个核心项目&#xff0c;由 Apache、Sun 和其他一些公司及个人共同开发而成。Tomc…

Python从入门到精通九:Python异常、模块与包

了解异常 什么是异常 当检测到一个错误时&#xff0c;Python解释器就无法继续执行了&#xff0c;反而出现了一些错误的提示&#xff0c;这就是所谓的“异常”, 也就是我们常说的BUG bug单词的诞生 早期计算机采用大量继电器工作&#xff0c;马克二型计算机就是这样的。 19…

元素定位,年轻人在 Web UI 自动化成长道路上吃的第一个亏

元素定位&#xff0c;对于 Web UI 自动化而言&#xff0c;绝对是大家成长道路上的一道绊脚石。很多初学者&#xff0c;都“死”在了元素定位上&#xff0c;从而失去了学习的兴趣。导致职业规划不得不半途而废~那么&#xff0c;今天&#xff0c;我们就使用 Katalon Studio&#…

我的创作三周年纪念日

今天收到CSDN官方的来信&#xff0c;创作三周纪念日到了。 Dear: Hann Yang &#xff0c;有幸再次遇见你&#xff1a; 还记得 2020 年 12 月 12 日吗&#xff1f; 你撰写了第 1 篇技术博客&#xff1a; 《vba程序用7重循环来计算24》 在这平凡的一天&#xff0c;你赋予了它…

Python编程技巧 – 使用组合运算符

Python编程技巧 – 使用组合运算符 Python Programming Skills – Using Combined Operators Python通过赋值过程&#xff0c;将声明变量与赋值和而为之&#xff0c;可谓讲求效率。此外&#xff0c;在Python赋值运算符里&#xff0c;也有一个强大高效的功能&#xff0c;即复合…

Python 神奇解码器:pyWhat 库全面指南

更多资料获取 &#x1f4da; 个人网站&#xff1a;ipengtao.com 在当今数字化的世界中&#xff0c;理解和处理文本数据是许多应用程序的关键任务。而PyWhat库作为一个用于处理文本的Python库&#xff0c;提供了强大的功能&#xff0c;帮助开发者在文本中识别和提取有意义的信息…

n-Track Studio Suite,音频录制与编辑的新纪元

在音乐制作领域&#xff0c;n-Track Studio Suite已经成为了音频录制和编辑的新标杆。这款软件将功能强大、操作简便和艺术创新完美融合&#xff0c;为用户提供了前所未有的音乐制作体验。 n-Track Studio Suite以其先进的音频处理技术&#xff0c;提供了精确的音频录制、编辑…

【从零开始学习JVM | 第三篇】类的生命周期(高频面试)

前言&#xff1a; 在Java编程中&#xff0c;类的生命周期是指类从被加载到内存中开始&#xff0c;到被卸载出内存为止的整个过程。了解类的生命周期对于理解Java程序的运行机制以及性能优化非常重要。 在本文中&#xff0c;我们将深入探讨类的生命周期&#xff0c;从类加载到…

VUE3语法--toRefs与toRef用法

1、功能概述 ref和reactive能够定义响应式的数据&#xff0c;当我们通过reactive定义了一个对象或者数组数据的时候&#xff0c;如果我们只希望这个对象或者数组中指定的数据响应&#xff0c;其他的不响应。这个时候我们就可以使用toRefs和toRef实现局部数据的响应。 toRefs是…

【探讨】bp神经网络是前馈还是后馈

目录 一、BP神经网络简介 1.1 什么是BP神经网络 1.2 BP神经网络的结构 二、BP神经网络的前馈与后馈 2.1 什么是BP神经网络的前馈 2.2 什么是BP神经网络的后馈 三、BP神经网络前馈与后馈的关系 3.1 BP神经网络前馈与后馈的区别 3.2 BP神经网络前馈与后馈的意义 四、BP…

论文阅读三——端到端的帧到凝视估计

论文阅读三——端到端的帧到凝视估计 主要内容研究问题文章的解题思路文章的主要结构 论文实验关于端到端凝视估计的数据集3种基线模型与EFE模型的对比在三个数据集中与SOTA进行比较 问题分析重要架构U-Net 基础知识 主要内容 文章从端到端的方法出发&#xff0c;提出了根据he…

Linux---虚拟机软件

1. 虚拟机软件的介绍 它是能够虚拟出来计算机的一个软件。 常用虚拟机软件: VmwareVirtualBox 说明: 只有安装了虚拟机软件才可以创建虚拟机&#xff0c;当然通过虚拟机软件还可以创建多个虚拟机。 2. 虚拟机的介绍 就是模拟一个真实的计算机&#xff0c;好比一个虚拟的…

Mybatis映射接口的动态代理实现原理

Mybatis映射接口的动态代理实现原理 在上一节中&#xff0c;我们介绍了MyBatis的核心配置文件加载流程&#xff0c;Mybatis核心配置文件加载流程详解 在文中&#xff0c;我们介绍了MyBatis在加载配置文件的过程中会针对每个接口类都生成一个相应的MapperProxyFactory动态代理工…

【异常解决】SpringBoot + Maven 在 idea 下启动报错 Unable to start embedded Tomcat(已解决)

Unable to start embedded Tomcat&#xff08;已解决&#xff09; 一、背景介绍二、原因分析2.1 网络上整理2.2 其他原因 三、解决方案 一、背景介绍 spring boot(v2.5.14) maven idea 启动项目 之前项目一直启动的好好的&#xff0c;都能正常运行。重启的时候突然就不能启…

单元测试技术

文章目录 一、单元测试快速入门二、单元测试断言三、Junit框架的常用注解 一、单元测试快速入门 所谓单元测试&#xff0c;就是针对最小的功能单元&#xff0c;编写测试代码对其进行正确性测试。 常规的例如如果在main中测试&#xff0c;比如说我们写了一个学生管理系统&…

MSPM0L1306例程学习-ADC部分(1)

MSPM0L1306例程学习-ADC部分(1) MSPM0L1306例程学习 使用的TI的官方例程&#xff0c;即SDK里边包含的例程代码。 MCU使用的是MSPM0L1306, 对于ADC部分&#xff0c;有10个例程&#xff1a; 例程理解 ADC的转换有多种工作模式&#xff0c;从最简单的单通道单次转换开始入手…

C++共享和保护——(1)作用域

归纳编程学习的感悟&#xff0c; 记录奋斗路上的点滴&#xff0c; 希望能帮到一样刻苦的你&#xff01; 如有不足欢迎指正&#xff01; 共同学习交流&#xff01; &#x1f30e;欢迎各位→点赞 &#x1f44d; 收藏⭐ 留言​&#x1f4dd; 人生就像骑单车&#xff0c;要想平衡就…

Java - Spring中Bean的循环依赖问题

什么是Bean的循环依赖 A对象中有B属性。B对象中有A属性。这就是循环依赖。我依赖你&#xff0c;你也依赖我。 比如&#xff1a;丈夫类Husband&#xff0c;妻子类Wife。Husband中有Wife的引用。Wife中有Husband的引用。 Spring解决循环依赖的机理 Spring为什么可以解决set s…

ubuntu如何远程ssh登录Windows环境并执行测试命令

ubuntu如何远程ssh登录Windows环境并执行测试命令 1 paramiko模块简介1.1 安装paramiko1.2 paramiko基本用法1.2.1 创建SSHClient实例1.2.2 设置主机密钥策略1.2.3 连接SSH服务器1.2.4 执行命令1.2.5 关闭SSH连接1.2.6 异常处理 2 windows的配置2.1 启动OpenSSH服务2.2 配置防火…