【JVM基础06】——组成-直接内存详解
目录
- 1- 引言:直接内存概述
- 1-1 直接内存是什么?直接内存的定义(What)
- 1-2 为什么用直接内存?Java程序对直接内存的使用 (Why)
- 2- ⭐核心:详解直接内存(How)
- 2-1 文件拷贝案例介绍对比常规 IO(BIO) 和 NIO
- 常规 IO 的操作流程
- NIO 的操作流程
- 3- 小结:
- 3-1 什么是直接内存?
1- 引言:直接内存概述
1-1 直接内存是什么?直接内存的定义(What)
- 直接内存:并不属于 JVM 中的内存结构,不由 JVM 进行管理。是虚拟机的系统内存,常见于 NIO 操作时,用于数据缓冲区,它分配回收成本较高,但读写性能高。
1-2 为什么用直接内存?Java程序对直接内存的使用 (Why)
- 高性能需求:直接内存的读写性能高于传统的JVM堆内存,因为减少了内存复制的次数。在进行大量数据的读写操作时,使用直接内存可以显著提高性能。
- NIO操作:Java NIO(Non-blocking IO)库通过使用直接内存来提升IO操作的吞吐量。直接内存允许Java程序直接访问操作系统的内存,从而减少了数据在系统缓冲区和Java堆缓冲区之间复制的开销。
- 资源共享:直接内存是操作系统内存的一部分,可以被操作系统和Java程序共享访问,这使得数据处理更加高效。
- 避免垃圾回收:直接内存不受JVM的垃圾回收机制影响,减少了由于垃圾回收导致的性能波动,对一些高性能应用场景尤为重要。
2- ⭐核心:详解直接内存(How)
2-1 文件拷贝案例介绍对比常规 IO(BIO) 和 NIO
- Java 代码完成文件拷贝
- 场景:
E:/bak1下有文件 需要拷贝到 ——>E:/bak2文件夹下

package com.heima.jvm;import java.nio.ByteBuffer;
import java.nio.channels.FileChannel;
import java.io.FileInputStream;
import java.io.FileOutputStream;public class DirectMemoryDemo {static final String FROM = "E:\\bak1\\01-java成神之路.mp4";static final String TO = "E:\\bak2\\abc.mp4";static final int _1Mb = 1024 * 1024;public static void main(String[] args) {io(); // 256.8563directBuffer(); // 63.2449}private static void directBuffer() {long start = System.nanoTime();try (FileChannel from = new FileInputStream(FROM).getChannel();FileChannel to = new FileOutputStream(TO).getChannel()) {ByteBuffer bb = ByteBuffer.allocateDirect(_1Mb);while (true) {int len = from.read(bb);if (len == -1) break;bb.flip();to.write(bb);bb.clear();}} catch (Exception e) {e.printStackTrace();}long end = System.nanoTime();System.out.println("NIO Time: " + (end - start) / 1e6 + " ms");}private static void io() {long start = System.nanoTime();try (FileInputStream fis = new FileInputStream(FROM);FileOutputStream fos = new FileOutputStream(TO)) {byte[] buffer = new byte[_1Mb];int len;while ((len = fis.read(buffer)) != -1) {fos.write(buffer, 0, len);}} catch (Exception e) {e.printStackTrace();}long end = System.nanoTime();System.out.println("IO Time: " + (end - start) / 1e6 + " ms");}
}

- 结果分析:NIO 比 BIO 效率更高
常规 IO 的操作流程
- Java本身不具备磁盘读写的能力,如果 Java 需要对磁盘进行读写,必须调用操作系统提供的函数(Native 修饰的本地方法)
①内存操作 ——> CPU状态切换
- Java程序运行在用户态(User Space),当需要进行磁盘读写操作时,必须切换到内核态(Kernel Space)。这种切换会消耗CPU资源。
②内存操作 ——> 数据读取和缓冲区使用:
- 通过调用操作系统的函数,将磁盘文件读取到系统缓存区中。
- 为了避免内存占用过大,操作系统利用缓冲区分批次读取数据。
③系统缓冲区与Java缓冲区的交互:
- 系统的缓冲区中 Java 代码无法直接运行,因此 Java 程序需要在堆内存中分配一块缓冲区(Java缓冲区)来存储数据,通常通过new byte[]的方式分配。
⑤数据复制:
- 数据从系统缓冲区复制到Java缓冲区。
- Java代码通过读取Java缓冲区中的数据进行操作。
- 由于存在两块缓冲区,数据需要在两块内存中存储两次,这会导致不必要的复制操作,从而降低效率。
问题所在:多次数据复制
- 因为数据需要从系统缓冲区复制到Java缓冲区,导致了数据的重复存储。
- 这种多次数据复制不仅消耗内存资源,还会影响整体性能。

NIO 的操作流程

- 在 NIO 的过程中,操作系统直接在内存中划分出了一个 直接内存 缓冲区, Java 代码也可以直接在直接访问直接内存。
- 直接内存对于操作系统和 Java 来说都是可以共享的区域,这就是直接内存。这就是直接内存带来的好处,直接提高了文件的 IO 操作。
3- 小结:
3-1 什么是直接内存?

相关文章:
【JVM基础06】——组成-直接内存详解
目录 1- 引言:直接内存概述1-1 直接内存是什么?直接内存的定义(What)1-2 为什么用直接内存?Java程序对直接内存的使用 (Why) 2- ⭐核心:详解直接内存(How)2-1 文件拷贝案例介绍对比常规 IO(BIO) 和 NIO常规 IO 的操作流程NIO 的操…...
学术研讨 | 区块链与隐私计算领域专用硬件研讨会顺利召开
学术研讨 近日,国家区块链技术创新中心主办,长安链开源社区支持的“区块链与隐私计算领域专用硬件研讨会”顺利召开,会议围绕基于区块链与隐私计算的生成式AI上链、硬件加速、软硬协同等主题展开讨论,来自复旦大学、清华大学、北京…...
AngularJS API 深入解析
AngularJS API 深入解析 AngularJS,作为一个强大且灵活的JavaScript框架,自从其诞生以来,就一直是前端开发者构建复杂Web应用的首选工具。本文将深入探讨AngularJS的API,帮助读者理解其核心功能和工作原理。 AngularJS简介 AngularJS由Google开发,并于2010年发布。它是…...
过某开源滑动验证码
过某开源滑动验证码 今天早上我有一点空闲时间,想着回顾一下前几天在某查询网站遇到的滑动验证码,以免时间久了忘记了。那个网站可能使用的是较早版本的开源滑块验证码系统tianai-captcha,但我不确定是否正确。 整体思路: 获取…...
一文解决 | Linux(Ubuntn)系统安装 | 硬盘挂载 | 用户创建 | 生信分析配置
原文链接:一文解决 | Linux(Ubuntn)系统安装 | 硬盘挂载 | 用户创建 | 生信分析配置 本期教程 获得本期教程文本文档,在后台回复:20240724。请大家看清楚回复关键词,每天都有很多人回复错误关键词…...
Matlab M_map工具箱绘制Interrupted Mollweide Projection
GMT自带了许多的地图投影,但是对于Interrupted Mollweide投影效果却不好。 作为平替的m_map工具箱中带有的投影类型可完美解决这一问题。 Interrupted Mollweide Projection长这样 全球陆地 全球海洋 使用Matlab工具箱m_map展示全球海平面变化的空间分布 addpath(…...
Python 变量与基本数据类型
重点内容 1 掌握变量及厂里在数据输入、输出及计算中的应用; 2 熟练使用datetime模块来处理日期和时间问题; 3 熟练掌握abs()、round()、pow()、sum()、min()、max()等的应用; 4 利用变量、字符等知识模拟开发中一些场景的输入与输出&…...
Pytorch深度学习实践(5)逻辑回归
逻辑回归 逻辑回归主要是解决分类问题 回归任务:结果是一个连续的实数分类任务:结果是一个离散的值 分类任务不能直接使用回归去预测,比如在手写识别中(识别手写 0 − − 9 0 -- 9 0−−9),因为各个类别…...
认识漏洞-GitLab 远程命令执行漏洞、致远OA-ajax.do未授权任意文件上传漏洞
为方便您的阅读,可点击下方蓝色字体,进行跳转↓↓↓ 01 [GitLab 远程命令执行漏洞复现(CVE-2021-22205)](https://mp.weixin.qq.com/s/4QT-vxKpBn4ppNM9ipt-nQ)02 [致远OA-ajax.do未授权任意文件上传Getshell](https://mp.weixin.qq.com/s/TH2A5J5TXU36Y…...
vue实现电子签名、图片合成、及预览功能
业务功能:电子签名、图片合成、及预览功能 业务背景:需求说想要实现一个电子签名,然后需要提供一个预览的功能,可以查看签完名之后的完整效果。 需求探讨:后端大佬跟我说,文档我返回给你一个PDF的oss链接…...
【flink】之如何消费kafka数据?
为了编写一个使用Apache Flink来读取Apache Kafka消息的示例,我们需要确保我们的环境已经安装了Flink和Kafka,并且它们都能正常运行。此外,我们还需要在项目中引入相应的依赖库。以下是一个详细的步骤指南,包括依赖添加、代码编写…...
科研绘图系列:R语言山脊图(Ridgeline Chart)
介绍 山脊图(Ridge Chart)是一种用于展示数据分布和比较不同类别或组之间差异的数据可视化技术。它通常用于展示多个维度或变量之间的关系,以及它们在不同组中的分布情况。山脊图的特点: 多变量展示:山脊图可以同时展示多个变量的分布情况,允许用户比较不同变量之间的关…...
Boost搜索引擎:如何建立 用户搜索内容 与 网页文件内容 之间的关系
如果想使“用户搜索内容”和“网页文件内容”之间产生联系,就应该将“用户搜索内容”和“网页文件”分为很小的单元 (这个单元就是关键词),寻找用户搜索单元是否出现在这个文档之中,如果出现就证明这个网页文件和用户搜…...
【QT】QT 窗口(菜单栏、工具栏、状态栏、浮动窗口、对话框)
Qt 窗口是通过 QMainWindow类来实现的。 QMainWindow 是一个为用户提供主窗口程序的类,继承自 QWidget 类,并且提供了⼀个预定义的布局。QMainWindow 包含一个菜单栏(Menu Bar)、多个工具栏(Tool Bars)、…...
Golang | Leetcode Golang题解之第283题移动零
题目: 题解: func moveZeroes(nums []int) {left, right, n : 0, 0, len(nums)for right < n {if nums[right] ! 0 {nums[left], nums[right] nums[right], nums[left]left}right} }...
ubuntu22.04 安装 NVIDIA 驱动以及CUDA
目录 1、事前问题解决 2、安装 nvidia 驱动 3、卸载 nvidia 驱动方法 4、安装 CUDA 5、安装 Anaconda 6、安装 PyTorch 1、事前问题解决 在安装完ubuntu之后,如果进入ubuntu出现黑屏情况,一般就是nvidia驱动与linux自带的不兼容,可以通…...
数据结构·AVL树
1. AVL树的概念 二叉搜索树虽可以缩短查找的效率,但如果存数据时接近有序,二叉搜索将退化为单支树,此时查找元素效率相当于在顺序表中查找,效率低下。因此两位俄罗斯数学家 G.M.Adelson-Velskii 和E.M.Landis 在1962年发明了一种解…...
记一次Mycat分库分表实践
接了个活,又搞分库分表。 一、分库分表 在系统的研发过程中,随着数据量的不断增长,单库单表已无法满足数据的存储需求,此时就需要对数据库进行分库分表操作。 分库分表是随着业务的不断发展,单库单表无法承载整体的数据存储时,采取的一种将整体数据分散存储到不同服务…...
数据分析:微生物数据的荟萃分析框架
介绍 Meta-analysis of fecal metagenomes reveals global microbial signatures that are specific for colorectal cancer提供了一种荟萃分析的框架,它主要基于常用的Wilcoxon rank-sum test和Blocked Wilcoxon rank-sum test 方法计算显著性,再使用分…...
Django—admin后台管理
Django官网 https://www.djangoproject.com/ 如果已经有了Django跳过这步 安装Django: 如果你还没有安装Django,可以通过Python的包管理器pip来安装: pip install django 创建项目: 使用Django创建一个新的项目: …...
【Axure高保真原型】引导弹窗
今天和大家中分享引导弹窗的原型模板,载入页面后,会显示引导弹窗,适用于引导用户使用页面,点击完成后,会显示下一个引导弹窗,直至最后一个引导弹窗完成后进入首页。具体效果可以点击下方视频观看或打开下方…...
pam_env.so模块配置解析
在PAM(Pluggable Authentication Modules)配置中, /etc/pam.d/su 文件相关配置含义如下: 配置解析 auth required pam_env.so1. 字段分解 字段值说明模块类型auth认证类模块,负责验证用户身份&am…...
从零开始打造 OpenSTLinux 6.6 Yocto 系统(基于STM32CubeMX)(九)
设备树移植 和uboot设备树修改的内容同步到kernel将设备树stm32mp157d-stm32mp157daa1-mx.dts复制到内核源码目录下 源码修改及编译 修改arch/arm/boot/dts/st/Makefile,新增设备树编译 stm32mp157f-ev1-m4-examples.dtb \stm32mp157d-stm32mp157daa1-mx.dtb修改…...
爬虫基础学习day2
# 爬虫设计领域 工商:企查查、天眼查短视频:抖音、快手、西瓜 ---> 飞瓜电商:京东、淘宝、聚美优品、亚马逊 ---> 分析店铺经营决策标题、排名航空:抓取所有航空公司价格 ---> 去哪儿自媒体:采集自媒体数据进…...
Device Mapper 机制
Device Mapper 机制详解 Device Mapper(简称 DM)是 Linux 内核中的一套通用块设备映射框架,为 LVM、加密磁盘、RAID 等提供底层支持。本文将详细介绍 Device Mapper 的原理、实现、内核配置、常用工具、操作测试流程,并配以详细的…...
零基础在实践中学习网络安全-皮卡丘靶场(第九期-Unsafe Fileupload模块)(yakit方式)
本期内容并不是很难,相信大家会学的很愉快,当然对于有后端基础的朋友来说,本期内容更加容易了解,当然没有基础的也别担心,本期内容会详细解释有关内容 本期用到的软件:yakit(因为经过之前好多期…...
MFC 抛体运动模拟:常见问题解决与界面美化
在 MFC 中开发抛体运动模拟程序时,我们常遇到 轨迹残留、无效刷新、视觉单调、物理逻辑瑕疵 等问题。本文将针对这些痛点,详细解析原因并提供解决方案,同时兼顾界面美化,让模拟效果更专业、更高效。 问题一:历史轨迹与小球残影残留 现象 小球运动后,历史位置的 “残影”…...
JS手写代码篇----使用Promise封装AJAX请求
15、使用Promise封装AJAX请求 promise就有reject和resolve了,就不必写成功和失败的回调函数了 const BASEURL ./手写ajax/test.jsonfunction promiseAjax() {return new Promise((resolve, reject) > {const xhr new XMLHttpRequest();xhr.open("get&quo…...
怎么让Comfyui导出的图像不包含工作流信息,
为了数据安全,让Comfyui导出的图像不包含工作流信息,导出的图像就不会拖到comfyui中加载出来工作流。 ComfyUI的目录下node.py 直接移除 pnginfo(推荐) 在 save_images 方法中,删除或注释掉所有与 metadata …...
tauri项目,如何在rust端读取电脑环境变量
如果想在前端通过调用来获取环境变量的值,可以通过标准的依赖: std::env::var(name).ok() 想在前端通过调用来获取,可以写一个command函数: #[tauri::command] pub fn get_env_var(name: String) -> Result<String, Stri…...
