当前位置: 首页 > news >正文

java中使用mmap技术简介

前言

jdk21 之后,随着 FFM 加入并稳定,现在 java 中也可以直接使用 mmap 技术将文件直接映射进内存并读取了,并且没有 nio 中 21 亿的限制(Integer.MAX_VALUE)。

BIO时代

try (FileInputStream fis = new FileInputStream("file.txt")) { byte[] buffer = new byte[8192]; // 8KB 缓冲区 int bytesRead; while ((bytesRead = fis.read(buffer)) != -1) { // 处理 buffer 中的前 bytesRead 字节 } }

最早读取文件就是阻塞读取,由于 byte[] 是jdk管理,自己传入的,所以下标最大就是21亿,而且由于正常情况下由代码传入,所以不可能 new byte[Integer.MAX_VALUE],而且 byte[] 回收需要看 gc。

NIO时代(JDK 1.4+)

try (FileChannel channel = FileChannel.open(Paths.get("data.txt"), StandardOpenOption.READ)) { MappedByteBuffer buffer = channel.map(FileChannel.MapMode.READ_ONLY, 0, size); }

后来 java 推出了 NIO,但是作者本人实际工作接触的需要如此优化的场景太少,且 api 并不直观,导致完全没有用过几次。返回的 MappedByteBuffer api 中下标参数使用的是 int,这直接导致超过 4G 的文件必须分段映射,且 MappedByteBuffer 映射的内存也需要 gc 回收。

属于初代 mmap 技术,虽然原理上是 mmap,但是限制颇多。

AIO时代(JDK 7+)

本质上是 NIO.2,或者叫 new NIO,原则上属于NIO的一部分

AsynchronousFileChannel

这个 api 更是查无此人,作者并不知道这个应该怎么用/有什么性能。

FFM(JDK 22+)

try (var arena = Arena.ofConfined(); var channel = FileChannel.open(path, StandardOpenOption.READ)) { var size = channel.size(); var memorySegment = channel.map(FileChannel.MapMode.READ_ONLY, 0, size, arena ); } catch (IOException e) { throw new RuntimeException(e); }

随着 FFM 稳定,原本的 FileChannel api 中也加入了对 FFM 的支持,使用 Arena 配置接下来申请的内存的生命周期管理,再将 arena 传入 channel,返回 MemorySegment,使用 MemorySegment 即可对全文件进行随机读写。arena 关闭后申请的所有内存直接回收,没有 gc 压力。

由于调用的是底层的 mmap 返回的内存段,所以直接读写 memorySegment 即可直接反应到文件上,也可以调用 MemorySegment#force() 强制写入。

更加接近底层的 mmap 技术,可选择是否有 gc 压力。

读取示例:

public class MemorySegmentFileTest { private static final Path path = Path.of("/home/bin-/Downloads/home/extraData.img"); static void main() { try (var arena = Arena.ofConfined(); var channel = FileChannel.open(path, StandardOpenOption.READ)) { var size = channel.size(); var memorySegment = channel.map(FileChannel.MapMode.READ_ONLY, 0, size, arena ); System.out.println("成功映射文件,大小:" + printSize(size)); System.out.println("内存段地址:" + memorySegment.address()); System.out.println("内存段大小:" + printSize(memorySegment.byteSize())); System.out.println("内存段内容前16字节:"); for (long i = 0; i < 16; i++) { byte b = memorySegment.get(ValueLayout.JAVA_BYTE, i); System.out.printf("0x%02X ", b); } System.out.println(); System.out.println("内存段内容后16字节:"); for (long i = size - 16; i < size; i++) { byte b = memorySegment.get(ValueLayout.JAVA_BYTE, i); System.out.printf("0x%02X ", b); } System.out.println(); } catch (IOException e) { throw new RuntimeException(e); } } private static String printSize(long size) { String[] units = {"B", "KiB", "MiB", "GiB", "TiB", "PiB", "EiB"}; long s = size; var list = new ArrayList<String>(); var builder = new StringBuilder(); var formatter = new Formatter(builder); for (var unit : units) { int sub = (int) (s & ((1 << 10) - 1)); formatter.format("%s %s", sub, unit); list.add(builder.toString()); builder.setLength(0); if (s < 1024) { break; } s >>= 10; } return String.join(" ", list.reversed()); } }

原理说明

mmap 只是建立了虚拟内存地址到磁盘文件的映射,并没有真正加载数据(Lazy Loading)。只有真正读取数据时,OS 才会发生缺页中断(Page Fault)去加载数据。

类似应用

  • 数据库系统:SQLite、MySQL、Redis
  • Kafka
  • RocketMQ

已知缺点

  • 本质是在借用 OS 的 Page Cache,如果同时运行数据库(MySQL/Redis)等应用,java 使用 mmap 疯狂读取大文件可能会把数据库在 Page Cache 里的热数据挤出去(Eviction)。

结尾

本文只是提出一种新版本 jdk 的全新 mmap 使用方式,与其他相对较老的方式相比,这种方式可以直接操纵堆外内存,且性能更高,还支持随机读取,唯一缺点可能就是 api 太新,用起来可能需要重新研究写法。

http://www.jsqmd.com/news/308292/

相关文章:

  • 7个技巧掌握鸿蒙远程调试与跨设备控制:HOScrcpy实战指南
  • 美团面试:熟悉哪些JVM调优参数
  • 重构了20个SpringBoot项目后,总结出这套稳定高效的架构设计
  • 解决技术协作痛点的Mermaid Live Editor:实时图表协作与可视化解决方案(附5个实战案例)
  • 思源宋体字重系统的视觉感知与工程实现研究
  • GLM-Z1-9B横空出世:90亿参数轻量模型性能开源新高度
  • Java 进化论:从语法糖到并发革命 —— 架构师视角下的 8 到 21
  • Baritone智能导航系统在Minecraft 1.21锻造自动化中的应用方案
  • 模板类与友元
  • 定制你的B站体验:BewlyBewly插件全方位个性化指南
  • 2026最新数据分析BI推荐!深圳/珠海优质数据分析BI服务商权威榜单发布,技术实力与服务体验双优助力企业数字化转型
  • 2026年高价值域名交易平台推荐
  • 性能测试核心概念与要点梳理
  • 30岁转行AI,是否可行?大模型学习全攻略:从零基础到AI专家的逆袭之路
  • 软件测试之功能测试详解
  • 支持无限开号的AI客户行为追踪名片小程序源码 带完整的搭建部署教程以及源代码包
  • 资源下载工具完全指南:无水印保存与批量采集实用技巧
  • 免费实现显卡性能跃升:让所有显卡型号无关的游戏体验升级方案
  • 全国雅思网课一对一培训机构排行推荐-2026权威出国雅思课程中心学校口碑排行榜
  • 多模态大语言模型下游微调全攻略:3大策略详解与实战指南
  • [MCP] Changes
  • 2026最新飞书推荐!数字化转型工具权威榜单发布,高效协同与智能管理双引擎驱动企业升级 深圳/广州飞书服务公司推荐
  • 2026年哪家红外压片机售后服务好?品牌推荐
  • 2026年GEO优化服务商怎么选?中小企业“可验证交付”决策指南(含对比表+合同验收清单)
  • 全国雅思网课一对一培训机构排行推荐,2026权威出国雅思课程中心学校口碑排行榜
  • 2026年企业需要建设网站哪家公司靠谱?
  • 全国雅思网课一对一培训机构排行推荐、2026权威出国雅思课程中心学校口碑排行榜
  • 革新性视频下载工具:3步搞定高清视频保存与离线观看
  • 全国雅思网课一对一培训机构排行推荐;2026权威出国雅思课程中心学校口碑排行榜
  • 2026全国最新家装品牌top10推荐!南昌等地优质家装公司权威榜单发布,资质服务双优助力打造理想家居