JVM工作原理与实战(二十):直接内存

前言

JVM作为Java程序的运行环境,其负责解释和执行字节码,管理内存,确保安全,支持多线程和提供性能监控工具,以及确保程序的跨平台运行。本文主要介绍了直接内存、在直接内存上创建数据等内容。


一、直接内存

在探讨直接内存之前,首先需要理解Java虚拟机(JVM)的运行时数据区。在《Java虚拟机规范》中,定义了几个关键的内存区域,如堆、方法区、程序计数器、Java虚拟机栈和本地方法栈。但直接内存,这一概念并不直接包含在《Java虚拟机规范》中。实际上,直接内存更多地是Java内存管理中的一个高级特性。

运行时数据区:

运行时数据区的详细讲解可以查看之前的文章:

JVM工作原理与实战(十五):运行时数据区-程序计数器 - 掘金 (juejin.cn)

JVM工作原理与实战(十六):运行时数据区-Java虚拟机栈 - 掘金 (juejin.cn)

JVM工作原理与实战(十七):运行时数据区-栈内存溢出 - 掘金 (juejin.cn)

JVM工作原理与实战(十八):运行时数据区-堆 - 掘金 (juejin.cn)

JVM工作原理与实战(十九):运行时数据区-方法区 - 掘金 (juejin.cn)

1.直接内存作用

直接内存(Direct Memory)的引入与JDK 1.4中的新IO(NIO)机制紧密相关。NIO为Java提供了非阻塞的I/O操作,从而允许更高的并发性和更高效的I/O处理。而直接内存正是NIO实现的关键部分:

  • 解决对象回收问题:在Java中,当堆上的对象不再被引用时,这些对象将被标记为可回收。这个过程可能会影响正在运行的应用程序,因为垃圾回收器可能需要停止或阻塞应用程序线程以完成其工作。直接内存通过减少堆上的对象数量来减轻这种影响。通过将数据直接存储在直接内存中,应用程序可以持续运行,而不必担心垃圾回收器可能带来的暂停或阻塞。
  • 减少数据复制开销:传统的IO操作,如读取文件,通常涉及两个步骤:首先将数据从文件读入到缓冲区(通常是直接内存),然后再从缓冲区复制到Java堆上的对象。这种双重数据复制不仅增加了延迟,还增加了CPU和内存的使用。通过使用直接内存作为缓冲区,NIO可以直接在直接内存中处理数据,从而减少了数据从缓冲区到堆的复制过程,提高了IO操作的效率。

直接内存的出现不仅提高了Java应用程序的性能,而且也增加了应用程序对并发和大数据处理的适应能力。通过使用直接内存,应用程序可以更有效地管理其资源,同时提高其响应速度和吞吐量。

二、在直接内存上创建数据

Java NIO提供了一种机制,允许在直接内存上创建数据。要实现这一目标,可以使用ByteBuffer的allocateDirect方法,size参数表示希望分配的直接内存的大小,单位为字节。

ini 复制代码
    ByteBuffer directBuffer = ByteBuffer.allocateDirect(size);

查看Java虚拟机的直接内存大小,可以使用arthas的memory命令,通过在命令行中输入memory来查看输出中的"direct"属性。

特殊情况下,可能需要手动调整直接内存的大小。可以通过设置JVM参数-XX:MaxDirectMemorySize来实现,这个参数允许开发者指定直接内存的最大大小。在设置-XX:MaxDirectMemorySize参数时,可以使用k或K表示千字节,m或M表示兆字节,g或G表示千兆字节,如果不设置这个参数,JVM会自动选择最大的分配大小。

案例:

arduino 复制代码
public class Demo1 {
    public static int size = 1024 * 1024 * 100;
    public static List<ByteBuffer> list = new ArrayList<ByteBuffer>();
    public static int count = 0;

    public static void main(String[] args) throws IOException, InterruptedException {
        System.in.read();
        while (true) {
            ByteBuffer directBuffer = ByteBuffer.allocateDirect(size);
            list.add(directBuffer);
            System.out.println(++count);
        }
    }
}

运行结果:

设置直接内存的大小:

ini 复制代码
-XX:MaxDirectMemorySize=1g

运行结果:


总结

JVM是Java程序的运行环境,负责字节码解释、内存管理、安全保障、多线程支持、性能监控和跨平台运行。本文主要介绍了直接内存、在直接内存上创建数据等内容,希望对大家有所帮助。

相关推荐
带刺的坐椅1 天前
Solon AI Skills 会是 Agent 的未来吗?
java·agent·langchain4j·solon-ai
jacGJ1 天前
记录学习--文件读写
java·前端·学习
花间相见1 天前
【JAVA开发】—— Nginx服务器
java·开发语言·nginx
扶苏-su1 天前
Java---Properties 类
java·开发语言
cypking1 天前
四、CRUD操作指南
java
橙子家1 天前
WebAPI 项目通过 CI/CD 自动化部署到 Linux 服务器(docker-compose)
后端
2301_780669861 天前
文件字节流输出、文件复制、关闭流的方法
java
剑锋所指,所向披靡!1 天前
C++之类模版
java·jvm·c++
钟离墨笺1 天前
Go语言--2go基础-->基本数据类型
开发语言·前端·后端·golang
Coder_Boy_1 天前
基于SpringAI的在线考试系统-0到1全流程研发:DDD、TDD与CICD协同实践
java·人工智能·spring boot·架构·ddd·tdd