FileChannle 和 MMAP 高性能分析

产品经理必看!用Cursor自动生成符合开发规范的技术文档(含UI设计规则模板) 本文详细介绍了产品经理如何利用Cursor工具自动生成符合开发规范的技术文档,并整合UI设计规则模板。通过配置标准化文档结构和设计关联规则,Cursor能有效解决术语不统一、结构混乱等问题,提升跨团队协作效率。文章包含实际案例、规则配置要点及企业级实施方案,帮助产品经理快速掌握AI辅助文档生成技巧。 阅读详情

前言

上一篇的博客中,我从底层上分析了BufferInputStream为什么效率会比FileInputStream来得高,这两种方式都是传统的IO,在JDK1.4 中NIO又多了两种新的IO方式:FileChannle 和 MMAP。这里着重来解释FileChannle的高性能的场景。

FileChannle

FileChannel 存在于 java.nio 包中,属于 NIO 的一种,但是注意 NIO 并不一定意味着非阻塞,这里的 FileChannel 就是阻塞的。那么这种新IO较与传统的IO有哪些优势呢?

其实这么说不够严谨,因为你必须用对了FileChannle,不然不存在优势之说。如何用对,就需要先从FileChannle的特点入手,FileChannel 采用了 ByteBuffer 这样的内存缓冲区,让我们可以非常精准的控制写盘的大小,这是普通 IO 无法实现的。

简单来说,传统的IO写数据时,先是往pagecache写入数据,不会马上刷到磁盘,而是将 pagecache 对应的位置标记为脏页,然后内核程序会定时将脏页的数据统一刷到磁盘中,但是为了安全起见,如果突然断电了pagecache中的数据就会丢失,所以这个定时的时间还不能太长,但我们希望的是,每次刷盘的尽可能在脏页比较多的情况下,不然对磁盘的写入效率太低。

而 FileChannel 将ByteBuffer 中的数据也不会马上写入到磁盘中,也是先写到pagecache,但是FileChannel 可以控制写盘的大小,它当然会尽可能写满一块数据块,然后再调用 force() 方法,用于通知操作系统进行及时的刷盘。

所以要想提高FileChannle的效率,必须要了解当前磁盘的数据库大小然后做出写盘大小的调整,这样效率才会快,从这方面也可以看出来FileChannle在读效率上并没有什么优势。

MMAP

关于内存映射,我在前面几篇的博客中已经对其做出了详细的解释,不明白的可以先看一下。

Linux shm和mmap
内存映射 mmap的理解(转载+整理)
RocketMQ 源码分析 消息存储(预备知识二)(转载+整理)

既然已经将了这么多关于内存映射,这里为什么还要再浪费口舌继续解释呢?主要是希望对NIO的方式有一个更加系统的认识。相信大家在网上经常能看到这么一段话来描述MMAP:普通文件被映射到进程地址空间后,进程可以像访问普通内存一样对文件进行访问,不必再调用read,write。 当时我是不能理解的,凭什么像访问内存一样速度就快呢?

要知道访问内存就意味着可以使用指针地址来访问了,虽然在Java中没有指针这种说法。那使用地址为什么速度就快了呢?比如你要读取一个文件开头的偏移1000个字节,传统的做法是不是一个for循环遍历到1000个字节,但是现在有了指针,你就可以直接指定position就可以访问了。如果每条实际的消息规定占用10个字节,那么访问的时候,就可以直接使用 文件的起始地址 + n*10 来访问第n条消息了,这也太方便了吧!!

mmap的读:

// 读
byte[] data = new byte[4];
int position = 8;
//从当前 mmap 指针的位置读取 4b 的数据
mappedByteBuffer.get(data);
//指定 position 读取 4b 的数据
MappedByteBuffer subBuffer = mappedByteBuffer.slice();
subBuffer.position(position);
subBuffer.get(data);

看到这是我在想,在RMQ中commitlog的偏移量存储在了Consume Queue中,这样是不是就可以利用上面访问内存的特性,根据偏移量快速定位到一条消息呢?只是我的猜测,如果有错,希望有大神能纠正。

同样的也可以指定position进行读写,mmap的读写:

// 写
byte[] data = new byte[4];
int position = 8;
//从当前 mmap 指针的位置写入 4b 的数据
mappedByteBuffer.put(data);
//指定 position 写入 4b 的数据
MappedByteBuffer subBuffer = mappedByteBuffer.slice();
subBuffer.position(position);
subBuffer.put(data);

参考文章

文件IO操作的一些最佳实践

IPsec (主模式,野蛮模式) IPsec vpn的主模式和野蛮模式 阅读详情

相关推荐

find命令

命令是 Linux/Unix 系统中用于搜索文件和目录的强大工具,支持多种搜索条件组合,并能对搜索结果执行各种操作。以下是其详细说明、常用参数及示例: 搜索路径:指定起始目录(如 、 或 表示当前目录)。 查找条件:基于文件名、类型、大小、时间等属性过滤。 处理动作:对匹配结果执行操作(如打印、删除、执行命令等)。 常用参数及示例 1. 按名称查找 :区分大小写匹配文件名。 :不区分大小写匹配文件名。 2. 按文件类型查找 :指定文件类型。 文件类型: :普通文件 :目录 :符号链接

qiao2458的博客 1134

文件IO操作的最佳实践

01 /背景/ 已经过去的中间件性能挑战赛,和正在进行中的 第一届 PolarDB 数据性能大赛 都涉及到了文件操作,合理地设计架构以及正确地压榨机器的读写性能成了比赛中获取较好成绩的关键。正在参赛的我收到了几位公众号读者朋友的反馈,他们大多表达出了这样的烦恼:“对比赛很感兴趣,但不知道怎么入门”,“能跑出成绩,但相比前排的选手,成绩相差10倍有余”…为...

weixin_34345560的博客 293

【外挂编程】外挂编程技术揭秘(二)

引言: 经过上一篇文章大家可能对外挂有了一个初步的认识,之前的内容比较简单,应该大家很容易掌握。我写作过程中我发现三个篇幅可能写不完,后续还可能要多加几个篇幅,这篇我们就先以内存挂为主吧。话不多说了,让我们开始吧。 文章中代码github地址: https://github.com/Diamonds-ZhaoYu/hz_example 环境要求: 系统:Windows 语言...

c-rain 4032

【linux】NIO中的FileChannel与mmap

FileChannel是Java NIO库中的一个类,用于对文件进行读写操作。它提供了一种高效的方式来读取、写入和操作文件。

morris 1万+

DS250DF410寄存器配置实战:从原理到调试的高速SerDes信号优化指南

在高速串行通信领域,SerDes(串行器/解串器)技术是实现芯片间高速数据传输的核心。其工作原理是通过时钟数据恢复(CDR)从串行数据流中提取时钟,并利用均衡技术补偿信道损耗。这项技术的核心价值在于突破PCB走线或电缆的带宽限制,确保在25Gbps及以上速率下数据的可靠传输。其应用场景广泛覆盖数据中心、高性能计算和通信设备中的高速背板、光模块及芯片互连。本文以TI的DS250DF410多通道重定时器为例,深入剖析其寄存器配置,特别是如何通过精细调控其自适应均衡器和眼图监测模块,实现对高速链路的信号整形与质量

aodiyi6351的博客 386

交换机救命命令手册:华为 & 思科平台最全运维指令速查表

很多时候,真正拉你一把的不是“高深理论”,而是你手里有没有一份靠得住的命令速查表。这篇文章,希望能成为你“进可调试,退可排障”的一份救命卡片。

HuaweiLab_Peach的博客 1515

Java Mmap理解

java mmap

developerFBI的专栏 625

NSIDC海冰运动产品-速度矢量场图绘制(数据下载和处理--年、季节平均)【python/basemap】

入门级NSIDC海冰运动产品速度矢量场图绘制(数据下载和处理--年、季节平均)【python/basemap】

Mluoo的博客 2959

NIO源码解析-FileChannel高阶知识点map和transferTo、transferFrom

前言: 上文我们介绍了下FileChannel的基本API使用。本文中,我们就一起看下FileChannel中的高阶API。 说是高阶,还真的就是,这些知识点大量利用了操作系统的对文件传输映射的高级玩法,极大的提高了我们操作文件的效率。我们熟知的kafka、rocketMQ等也是用了这些高阶API,才有如此的高效率。 我们提出一个需求,描述如下:提供一个对外的socket服务,该服务就是获取指定文件目录下的文件,并写出到socket中,最终展现在client端。 1.传统...

恐龙弟旺仔的博客 3649

YOLOv11垃圾检测实战:从零搭建带GUI的智能分类系统(附完整数据集)

本文详细介绍了如何从零开始构建一个基于YOLOv11的智能垃圾检测系统,并集成图形化界面。内容涵盖数据集构建与增强、模型选型与轻量化改进(如引入注意力机制),以及使用PyQt5开发稳定GUI的完整流程,旨在解决实际部署中精度与速度的平衡问题,为环保科技等应用场景提供可落地的解决方案。

646

阿里云习题多选部分459道

比如: UserA的用户在杭州有一台经典网络的ECS云服务器InstanceA (内网IP: A.A.A),InstanceA所属的默认安全组为GroupA, UserB的用户在杭州有一台经 典网络的ECS云服务器InstanceB(内网IP:B.B.B),InstanceB所属的默认安全组为GroupB。43.创建阿里云的云服务器ECS实例之前,需要对ECS实例的配置进行选型,阿里云为用户提供了推荐的配置组合方案来满足大部分用户的需求,这些推荐配置只是作为开始使用云服务器ECS实例的参考。

2501_91384465的博客 1309

Java网络编程与NIO详解8:浅析mmap和Direct Buffer

本文转自:https://www.cnblogs.com/huxiao-tee/p/4660352.html 本系列文章将整理到我在GitHub上的《Java面试指南》仓库,更多精彩内容请到我的仓库里查看 https://github.com/h2pl/Java-Tutorial 喜欢的话麻烦点下Star哈 文章将同步到我的个人博客: www.how2playlife.com 本文...

AliCoder的博客 1376

Ollama模型路径迁移实战:Windows/Mac/Linux三平台保姆级教程(附常见问题排查)

本文提供了一份详细的Ollama模型路径迁移教程,涵盖Windows、macOS和Linux三大平台。通过设置OLLAMA_MODELS环境变量或创建符号链接,指导用户将模型从默认路径安全迁移至新位置,以释放系统盘空间或提升性能。教程包含迁移前的准备、分平台步骤、迁移后的验证以及常见问题排查,确保迁移过程平滑可靠。

js777的博客 1184

java map failed_java.lang.OutOfMemoryError:Map failed总结

常见的OOM是以下这几种:1.GC overhead limit exceeded2.Java Heap Space3.Unable to create new native thread4.PermGen Space5.Direct buffer memory6.request {} bytes for {}. Out of swap space?一直自认为不会有超过这个范围的OOM类型出现,没...

weixin_26945061的博客 410

IEM模型,地表粗糙度模拟

利用微波反演土壤水分时候,利用IEM模型可以实现对随机地表的模拟

RU DOS版、EFI版32bit/64bit BIOS常用工具

DOS版、EFI版的RU工具,可用来查看IO、MEM、PCI、SMBIOS等资源。亲测在EFI SHELL下可用。

java filechannel 性能_NIO中FileChannel和MappedByteBuffer原理和性能对比

MappedByteBuffer实现MMAP(Memory Mapped Files)技术(内存映射)mmap(Memory Mapped Files),简单描述其作用就是:将磁盘文件映射到内存, 用户通过修改内存就能修改磁盘文件。它的工作原理是直接利用操作系统的Page来实现文件到物理内存的直接映射。完成映射之后你对物理内存的操作会被同步到硬盘上(操作系统在适当的时候)。通过mmap,进程像读写...

weixin_39793576的博客 510

老版QQ原生表情gif动态

这是老版的QQ表情,不过全是动态的的,Windows照片查看器是不会动的,可以右击用浏览器打开查看,再说一遍是老版的,只是分享给宁愿用老版也要动态的人。

FileChanel复制文件比传统方法慢?

试了下用FileChanel.transferTo复制一个4G多的文件,和用传统IO复制,发现FileChannel居然并没有更快。不懂为什么大文件(G级),用FIleChannel并没有优势,有大佬能解释吗?运行结果显示FileChannel并没有更快。调换顺序,影响不大。换200+M的文件试了下,fileChannel有明显优势。

wozhu_csdn的博客 544

精雕软件(JDpaint) 5.5 绿色版

精雕软件(JDpaint) 5.5 绿色版精雕软件(JDpaint) 5.5 绿色版精雕软件(JDpaint) 5.5 绿色版

Java之FileChannel类的理解和使用 -----java 流NIO的使用

1. FileChannel 使用场景: 一个读,写,映射,操作文件的通道。 2 使用的优点 1.在文件的绝对位置的字节读写操作在某种程度上不会影响通道的当前位置。 2.文件的区域可能会被直接映射到内存中,对于大文件来说,这比通常的读写方法更有效。 3.为了保证数据在系统崩溃之后不丢失数据,文件的修改模式会被强制到底层存储设备。 4.字节能从一个文件被转换为一些其他的通道,反之亦然,...

fight_man8866的博客 1679

java实践4之浅谈文件IO、实现带缓冲区读写、NIO、理解Bytebuffer核心参数、Mmap、零拷贝

java IO NIO filechannel mmap bytebuffer 堆外内存

m252131895的博客 1217

Java NIO学习之FileChannel

Java的FileChannel读文件方式

南风知我意 2048

java高速缓存大小设置_关于java:使用FileInputStream时如何确定理想的缓冲区大小?...

我有一个从文件创建MessageDigest(哈希)的方法,我需要对很多文件(> = 100,000)执行此操作。 为了使性能最大化,我应该为读取文件设置多大的缓冲区?大多数人都熟悉基本代码(为防万一,在此重复):MessageDigest md = MessageDigest.getInstance("SHA" );FileInputStream ios = new FileInputSt...

weixin_35089515的博客 2013

文件io和网络io

文件Io 一、输入及输出的概念 1.1 什么是 I/O 是指程序与外部设备或其他计算机进行交互的操作。 几乎所有的程序都具有输入与输出操作。 如从键盘上读取数据,从本地或网络_上的文件读取数据或写入数据等。 通过输入和输出操作可以从外界接收信息,或者是把信息传递给外界。 Java把这些输入与输出操作用流来实现,通过统一的接口来表示,从而使程序设计更为简单。 1.2 输入输出(I/0) 入还是出事相对于内存 把数据读到内存中,称为输入,即 input,进行数据的 read 操作 往内存外部设备写数据,称为输出

qq_37436172的博客 1429

BufferedInputStream 底层原理解析

前言 RMQ中为了实现高性能在IO上做了很多优化,在阿里中间件性能挑战赛也可以看到很多大神们在IO上花了很多功夫去分析优化,这篇主要来解析一下BufferedInputStream的实现原理,看看它在IO上做了哪些优化。 误区 看到很多文章是这么描述BufferedInputStream性能高的原因:BufferedInputStream 将数据先保存在了缓存区,从而减少磁盘IO操作次数,提高I...

没有进步就是退步 1441

java bio,nio(内存映射/零拷贝),aio(直接IO)

socket client:先来了解几个关键词: 1、DMA控制器:通俗来讲,就是操作内存和硬盘之间数据的复制,可以让当前线程释放CPU,在DMA出来之前,是由CPU来做这事的 2、pageCahe:就是一个高速缓冲区,缓存IO(大部分IO操作都是缓存IO)中用户态和内核态之间的一个桥梁 3、缓存IO,直接IO 缓存IO:大部分IO使用的一种方式 直接IO:在AIO(nio2)中使用到 4、mmap:就是用户进程虚拟内存地址和内核内存间直接建立映射关系,用户态可以直接访问内核态.

beiduofen2011的专栏 1499

重新认识 Java 中的内存映射(mmap)

恰恰和网传的很多言论相反,mmap 由于其不切态的特性,特别适合顺序读写,但由于 sun.nio.ch.FileChannelImpl#map(MapMode mode, long position, long size) 中 size 的限制,只能传递一个 int 值,所以,单次 map 单个文件的长度不能超过 2G,如果将 2G 作为文件大 or 小的阈值,那么小于 2G 的文件使用 mmap 来读写一般来说是有优势的。一个实用的技巧是动态分配的内存映射区域,在读取过后,可以异步回收掉。

zhexiao 2453

fopen,open,mmap函数在Linux文件编程中的应用总结

fopen是C语言库函数,open是系统调用,mmap是将大文件映射到内存中使用。fopen与open函数区别网上有很多的介绍,但是大多数都是没有注意平台上的差异(特别是百度百科)。在Linux文件编程中,fopen函数的使用就有不少的坑,如果照搬百度上的定义,则有可能会出现异常的问题。 1.fopen函数 一般与fopen同时使用的还有fwrite,fread,fclose。

Biao 4146

论最强IO:MappedByteBuffer VS FileChannel

最近一直在研究MQ,开源社区中有很多高性能MQ:kafka、RocketMQ、ActiveMQ,抛开网络传输方式、数据结构设计、文件存储方式...等因素。Java 在 JDK 1.4 引入了 ByteBuffer 等 NIO 相关的类,使得 Java 程序员可以抛弃基于 Stream ,从而使用基于 Block 的方式读写文件。这些MQ有一个共同的特点就是:引入了 IO 性能优化之王MappedB...

布道 2万+
上一篇: BufferedInputStream 底层原理解析
下一篇: 多线程并发 之 synchronized 锁的优化
CallMeJiaGu
博客等级 码龄12年 149粉丝 99原创
评论 1
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

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

抵扣说明:

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

余额充值