【从零开始学习JVM | 第六篇】快速了解 直接内存
前言:
当谈及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对象的引用。

通过这种方式减少了数据复制的开销,提高了效率。
直接内存的优点:
- 无需垃圾回收:直接内存并不受Java堆的垃圾回收机制管理,不会占用宝贵的堆空间,也不会对垃圾回收器产生额外的压力。
- 与本地操作系统直接交互:直接内存是通过使用本地方法库(Native Libraries)来与操作系统进行交互的。这意味着可以利用操作系统提供的高效的内存管理功能,如零拷贝等。
- 基于操作系统的零拷贝:在使用直接内存进行I/O操作时,可以通过零拷贝技术将数据直接从直接内存传输到网络或磁盘上,避免了数据复制的开销,提高了性能。
- 分配和释放成本较高:由于直接内存需要与操作系统进行交互,所以它的分配和释放成本相对较高,而且需要谨慎管理以避免资源泄漏。
如何操作直接内存:
JAVA代码方式:
在Java中,可以使用 java.nio.ByteBuffer 类来创建直接内存数据。直接内存是通过操作系统分配的内存,不受 Java 堆内存大小的限制,通常用于需要频繁 I/O 操作的场景。
import java.nio.ByteBuffer;public class DirectMemoryExample {public static void main(String[] args) {// 分配直接内存,创建一个容量为 10 字节的 ByteBufferByteBuffer 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使用场景:
-
网络编程:在网络通信中,需要频繁地进行数据的读取和发送,如果使用堆内存,就需要将数据先读入堆内存,再复制到网络缓冲区中,这样会增加不必要的开销。使用直接内存,可以直接将数据映射到网络缓冲区,避免数据复制,提高了网络通信的效率。
-
文件操作:在读写大文件时,使用传统的文件读写方式,需要将数据先读入堆内存,再进行处理。使用直接内存,可以直接将文件映射到内存中,避免了数据复制,减少了 I/O 操作的次数,提高了文件读写的效率。
-
图像处理和多媒体应用:在图像处理和多媒体应用中,需要频繁地进行像素数据的读取和处理。使用直接内存,可以将像素数据映射到内存中,避免了数据复制,提高了图像处理和多媒体应用的效率。
需要注意的是,使用直接内存时需要特别谨慎,因为直接内存是由操作系统分配的,不受 JVM 垃圾回收机制的管理,如果分配过多的直接内存,可能会导致操作系统资源耗尽,从而影响系统的稳定性。因此,在使用直接内存时,需要根据实际情况合理设置直接内存的大小,并在使用完毕后及时释放直接内存。
总结:
总的来说,JVM 直接内存在现代 Java 应用程序中扮演着重要的角色。它主要用于提高 I/O 操作的效率,特别是在涉及网络通信、文件操作和大规模数据处理时。通过直接内存,可以避免数据的额外复制,直接在操作系统级别操作数据,从而提高了应用程序的性能和吞吐量。
然而,使用直接内存也需要谨慎对待。由于直接内存不受 JVM 垃圾回收机制管理,过度使用可能导致操作系统资源耗尽,影响系统的稳定性。因此,在使用直接内存时,需要合理设置直接内存的大小,并确保及时释放不再需要的直接内存,以避免潜在的问题。
综上所述,合理利用 JVM 直接内存可以有效提升 Java 应用程序的性能,但同时也需要注意资源管理和释放,以确保系统的稳定性和可靠性。
如果我的内容对你有帮助,请点赞,评论,收藏。创作不易,大家的支持就是我坚持下去的动力!

相关文章:
【从零开始学习JVM | 第六篇】快速了解 直接内存
前言: 当谈及Java虚拟机(JVM)的内存管理时,我们通常会想到堆内存和栈内存。然而,还有一种被称为"直接内存"的特殊内存区域,它在Java应用程序中起着重要的作用。直接内存提供了一种与Java堆内存和…...
Wireshark中的http协议包分析
Wireshark可以跟踪网络协议的通讯过程,本节通过http协议,在了解Wireshark使用的基础上,重温http协议的通讯过程。 TCP(Transmission Control Protocol,传输控制协议)是一种面向连接的、可靠的、基于 字节流…...
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 配置防火…...
人工智能应用专栏----专栏介绍
文章目录 本专栏主要记录人工智能的应用方面的内容,包括chatGPT、AI绘图等等; 订阅后可私聊我获取 《从零注册并登录使用ChatGPT》 《从零开始使用chatGPT的API;通过chatgpt-next-web部署自己chatGPT web网页;无需翻墙,…...
【lesson11】表的约束(4)
文章目录 表的约束的介绍唯一键约束测试建表插入测试建表插入测试建表插入测试修改表插入测试 表的约束的介绍 真正约束字段的是数据类型,但是数据类型约束很单一,需要有一些额外的约束,更好的保证数据的合法性,从业务逻辑角度保…...
将单体应用程序迁移到微服务
多年来,我处理过多个单体应用,并将其中一些迁移到了微服务架构。我打算写下我所学到的东西以及我从经验中用到的策略,以实现成功的迁移。在这篇文章中,我将以AWS为例,但基本原则保持不变,可用于任何类型的基…...
Python读取.dat格式数据并转为.png,.jpg,.bmp等可视化格式(附代码)
.dat文件的命名规则没有统一的规定,但通常以.dat为扩展名。 目录 一、 .dat格式数据1.1 .dat数据用途1.2 常见的.dat文件格式1.3 .dat文件示例 二、读取.dat格式数据2.1 单个.dat文件读取并转换2.1.1 代码2.1.2 查看数据2.1.3 输出查看8Bit图片 2.2 批量.dat文件读取…...
matplotlib 默认属性和绘图风格
matplotlib 默认属性 一、绘图风格1. 绘制叠加折线图2. Solarize_Light23. _classic_test_patch4. _mpl-gallery5. _mpl-gallery-nogrid6. bmh7. classic8. fivethirtyeight9. ggplot10. grayscale11. seaborn12. seaborn-bright13. seaborn-colorblind14. seaborn-dark15. sea…...
ip地址怎么转化为十进制
IP地址是在计算机网络中广泛使用的一种标识符,它用于唯一地标识网络上的设备。在网络通信过程中,IP地址扮演着非常重要的角色。但是,对于一些非专业人士来说,IP地址可能是一个陌生的概念。为了更好地理解IP地址,本文…...
【Spring进阶系列丨第五篇】详解Spring中的依赖注入
文章目录 一、说明二、构造函数注入2.1、方式一【index索引方式】2.1.1、定义Bean2.1.2、主配置文件中配置Bean2.1.3、测试 2.2、方式二【indextype组合方式】2.2.1、定义Bean2.2.2、主配置文件配置Bean2.2.3、测试2.2.4、解决方案 2.3、方式三【name方式】2.3.1、定义Bean2.3.…...
DAP数据集成与算法模型如何结合使用
企业信息化建设会越来越完善,越来越体系化,当今数据时代背景下更加强调、重视数据的价值,以数据说话,通过数据为企业提升渠道转化率、改善企业产品、实现精准运营,为企业打造自助模式的数据分析成果,以数据…...
大数据监控
HBase 监控 {name“RegionServer”,sub“Server”,} irate(hadoop_hbase_totalrequestcount[5m]) irate(hadoop_hbase_totalrequestcount{instanceName“hacluster4”}[2m]) https://blog.csdn.net/Samooyou/article/details/129275640 https://www.tencentcloud.com/zh/doc…...
【C语言】数据结构——小堆实例探究
💗个人主页💗 ⭐个人专栏——数据结构学习⭐ 💫点击关注🤩一起学习C语言💯💫 导读: 我们在前面学习了单链表和顺序表,以及栈和队列。 今天我们来学习小堆。 关注博主或是订阅专栏&a…...
Vue中比较两个JSON对象的差异
要在Vue.js中实现JSON数据的对比差异功能,你可以使用一些库来简化任务,比如diff-match-patch。以下是一个简单的例子,演示如何使用deep-diff库在Vue.js中比较两个JSON对象的差异: 首先,确保你的项目中已经安装了diff-m…...
前端知识库Html5和CSS3
1、常见的水平垂直居中实现方案 最简单的方案是flex布局 .container{display: flex;align-items: center;justify-content: center; }绝对定位配合margin:auto(一定要给.son宽高) .father {position: relative;height: 300px; } .son {position: absolute;top: 0;right: 0;b…...
智能优化算法应用:基于鸡群算法3D无线传感器网络(WSN)覆盖优化 - 附代码
智能优化算法应用:基于鸡群算法3D无线传感器网络(WSN)覆盖优化 - 附代码 文章目录 智能优化算法应用:基于鸡群算法3D无线传感器网络(WSN)覆盖优化 - 附代码1.无线传感网络节点模型2.覆盖数学模型及分析3.鸡群算法4.实验参数设定5.算法结果6.参考文献7.MA…...
Apollo配置发布原理解析
📫作者简介:小明java问道之路,2022年度博客之星全国TOP3,专注于后端、中间件、计算机底层、架构设计演进与稳定性建设优化,文章内容兼具广度、深度、大厂技术方案,对待技术喜欢推理加验证,就职于…...
TrustGeo论文问题理解
1、网络空间测绘中,如何理解地标? 在网络空间测绘中,地标可以理解为在互联网空间中具有明显特征和稳定性的实体,它们可以作为网络空间的基准点,用于定位和标识其他网络实体。地标通常是在网络空间中具有较高价值和影响…...
子查询在SQL中的应用和实践
作者:CSDN-川川菜鸟 在SQL中,子查询是一种强大的工具,用于解决复杂的数据查询问题。本文将深入探讨子查询的概念、类型、规则,并通过具体案例展示其在实际应用中的用途。 文章目录 子查询概念子查询的类型子查询的规则实际案例分析…...
C# Socket通信从入门到精通(14)——多个异步UDP客户端C#代码实现
前言: 在之前的文章C# Socket通信从入门到精通(13)——单个异步UDP客户端C#代码实现我介绍了单个异步Udp客户端的c#代码实现,但是有的时候,我们需要连接多个服务器,并且对于每个服务器,我们都有一些比如异步发送、异步接收的操作,那么这时候我们使用之前单个异步Udp客…...
P3 QT项目----记事本(3.8)
3.8 记事本项目总结 项目源码 1.main.cpp #include "widget.h" #include <QApplication> int main(int argc, char *argv[]) {QApplication a(argc, argv);Widget w;w.show();return a.exec(); } 2.widget.cpp #include "widget.h" #include &q…...
用docker来安装部署freeswitch记录
今天刚才测试一个callcenter的项目,所以尝试安装freeswitch 1、使用轩辕镜像 - 中国开发者首选的专业 Docker 镜像加速服务平台 编辑下面/etc/docker/daemon.json文件为 {"registry-mirrors": ["https://docker.xuanyuan.me"] }同时可以进入轩…...
纯 Java 项目(非 SpringBoot)集成 Mybatis-Plus 和 Mybatis-Plus-Join
纯 Java 项目(非 SpringBoot)集成 Mybatis-Plus 和 Mybatis-Plus-Join 1、依赖1.1、依赖版本1.2、pom.xml 2、代码2.1、SqlSession 构造器2.2、MybatisPlus代码生成器2.3、获取 config.yml 配置2.3.1、config.yml2.3.2、项目配置类 2.4、ftl 模板2.4.1、…...
云原生安全实战:API网关Kong的鉴权与限流详解
🔥「炎码工坊」技术弹药已装填! 点击关注 → 解锁工业级干货【工具实测|项目避坑|源码燃烧指南】 一、基础概念 1. API网关(API Gateway) API网关是微服务架构中的核心组件,负责统一管理所有API的流量入口。它像一座…...
安卓基础(Java 和 Gradle 版本)
1. 设置项目的 JDK 版本 方法1:通过 Project Structure File → Project Structure... (或按 CtrlAltShiftS) 左侧选择 SDK Location 在 Gradle Settings 部分,设置 Gradle JDK 方法2:通过 Settings File → Settings... (或 CtrlAltS)…...
通过MicroSip配置自己的freeswitch服务器进行调试记录
之前用docker安装的freeswitch的,启动是正常的, 但用下面的Microsip连接不上 主要原因有可能一下几个 1、通过下面命令可以看 [rootlocalhost default]# docker exec -it freeswitch fs_cli -x "sofia status profile internal"Name …...
【java】【服务器】线程上下文丢失 是指什么
目录 ■前言 ■正文开始 线程上下文的核心组成部分 为什么会出现上下文丢失? 直观示例说明 为什么上下文如此重要? 解决上下文丢失的关键 总结 ■如果我想在servlet中使用线程,代码应该如何实现 推荐方案:使用 ManagedE…...
当下AI智能硬件方案浅谈
背景: 现在大模型出来以后,打破了常规的机械式的对话,人机对话变得更聪明一点。 对话用到的技术主要是实时音视频,简称为RTC。下游硬件厂商一般都不会去自己开发音视频技术,开发自己的大模型。商用方案多见为字节、百…...
PostgreSQL 与 SQL 基础:为 Fast API 打下数据基础
在构建任何动态、数据驱动的Web API时,一个稳定高效的数据存储方案是不可或缺的。对于使用Python FastAPI的开发者来说,深入理解关系型数据库的工作原理、掌握SQL这门与数据库“对话”的语言,以及学会如何在Python中操作数据库,是…...
linux设备重启后时间与网络时间不同步怎么解决?
linux设备重启后时间与网络时间不同步怎么解决? 设备只要一重启,时间又错了/偏了,明明刚刚对时还是对的! 这在物联网、嵌入式开发环境特别常见,尤其是开发板、树莓派、rk3588 这类设备。 解决方法: 加硬件…...
