C# 文件操作与内存管理单元(MMU) C#文件缓存是如何与虚拟内存和页面表交互的

老丽吖_5463

老丽吖_5463

2026-02-28

374人浏览

原创

File.ReadAllBytes 不会直接触发页面错误,但分配的大数组首次访问时可能因延迟提交机制引发缺页中断;其内存管理依赖CLR虚拟内存分配与OS按需调页,而非同步加载物理页。

c# 文件操作与内存管理单元(mmu) c#文件缓存是如何与虚拟内存和页面表交互的

File.ReadAllBytes 会触发页面错误吗

不会直接触发,但可能间接导致。C# 的 File.ReadAllBytes 是同步阻塞调用,它通过 Win32 ReadFile 读取文件到托管堆上新分配的 byte[]。这个数组本身是 GC 堆对象,其内存由 CLR 从虚拟内存中申请(通常走 VirtualAlloc),但此时只是保留地址空间,并未提交物理页——真正触发缺页中断(page fault)的是后续对该数组的首次写入或读取(取决于 OS 内存策略和 .NET 运行时是否启用零初始化优化)。

  • 如果文件很大(比如 >85KB),byte[] 会被分配在大对象堆(LOH),LOH 分配仍走虚拟内存管理,但 GC 不压缩,容易碎片化
  • Windows 默认启用“延迟提交”(commit on first access),所以 ReadAllBytes 返回后,数组内存可能尚未映射到物理页——直到你遍历、拷贝或传给另一个函数才真正拉起页面
  • 不要误以为“没报错就没开销”:大量小文件反复调用它,会在 LOH 留下大量短命大数组,加剧 GC 压力,间接拖慢虚拟内存管理效率

.NET 中 FileStream 的缓冲区与 MMU 无关

FileStream 的 bufferSize 参数(默认 4096)只控制托管层的读写缓存大小,和底层虚拟内存分页(4KB 页面)、页表项(PTE)、TLB 查找完全无关。它解决的是系统调用次数问题,不是内存映射问题。

  • 设置 bufferSize = 1 会让每次 Read 都发一次 ReadFile 系统调用,但每次系统调用申请的内核缓冲区仍是按页对齐分配的,不受你传的 buffer 大小影响
  • 开启 useAsync = true 后,.NET 会尝试使用 I/O 完成端口 + 内存池(ArrayPool.Shared),复用缓冲区,减少 LOH 分配——这才是影响内存压力的关键点,而非页表行为
  • 想绕过用户态缓冲直通物理页?不行。.NET 没提供 mmap-style 的内存映射文件暴露给 C# 层;MemoryMappedFile 是封装了 Windows CreateFileMapping,但它映射的是整个文件视图到进程虚拟地址空间,由 OS 负责按需调页,和 FileStream 的缓冲逻辑正交

MemoryMappedFile 读写时页面表怎么动

当你用 MemoryMappedFile.CreateFromFile 创建映射,再用 CreateViewAccessor 获取 MemoryMappedViewAccessor,实际是在进程的虚拟地址空间里划出一块区域,并在页表中添加对应 PTE 条目,初始状态通常是“无效”或“原型 PTE”。真实页面加载发生在第一次访问该地址时(软缺页)。

C#
C#

"避开 C# 常见错误——空陷阱、异步陷阱、LINQ 陷阱及资源泄漏。"

下载
  • 访问未加载的页面 → 触发缺页异常 → OS 查页表发现是映射文件 → 从磁盘读取对应文件块 → 分配物理页 → 更新 PTE → 恢复执行。这个过程对 C# 代码完全透明
  • 如果文件被多个进程映射,且都设为 PageReadWrite,修改后是否立即落盘?不一定。Windows 默认使用“写时复制+延迟写入”,脏页由系统工作线程在空闲时刷回磁盘,或由 Flush 强制触发
  • 注意 Dispose 顺序:ViewAccessor 先释放,再 MemoryMappedFile,否则可能抛 ObjectDisposedException;但即使正确释放,页表项清除和物理页回收也是异步的,不保证立刻归还内存

为什么不用 MemoryMappedFile 就觉得“没走 MMU”

这是一种错觉。所有用户态内存访问(包括 new byte[1024]、StringBuilder、List)都经过 MMU 和页表——只是路径更短:分配时预留 VA,首次访问时提交物理页,之后全程 TLB 命中,几乎无感知。而 MemoryMappedFile 把“页面加载时机”显性暴露出来了,让人误以为它是唯一和 MMU 打交道的方式。

  • 普通文件读取(ReadAllBytes / StreamReader)也会让 OS 在内核中分配缓冲区,那些缓冲区内存同样受虚拟内存管理,只是你不直接碰地址
  • 真正绕过 MMU 的场景极少,比如 DMA 直接写设备内存(需要驱动支持)、或使用 Unsafe.AsPointer + NativeMemory.Alloc 配合 VirtualLock 锁定物理页——但这些在常规业务中既没必要,也极难安全使用
  • 排查内存占用高?别盯着“MMU 是否参与”,先看 GC 堆快照(dotnet-gcdump)、LOH 占比、文件流是否忘记 Dispose——大部分时候问题出在托管资源生命周期,不在页表更新延迟

相关文章

PHP速学视频免费教程(入门到精通)
PHP速学视频免费教程(入门到精通)

PHP怎么学习?PHP怎么入门?PHP在哪学?PHP怎么学才快?不用担心,这里为大家提供了PHP速学教程(入门到精通),有需要的小伙伴保存下载就能学习啦!

下载

相关标签:

虚拟内存 c#

本站声明:本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系admin@php.cn

相关专题

更多
堆和栈的区别
堆和栈的区别

堆和栈的区别:1、内存分配方式不同;2、大小不同;3、数据访问方式不同;4、数据的生命周期。本专题为大家提供堆和栈的区别的相关的文章、下载、课程内容,供大家免费下载体验。

2023.07.18

6367

5

堆和栈区别
堆和栈区别

堆(Heap)和栈(Stack)是计算机中两种常见的内存分配机制。它们在内存管理的方式、分配方式以及使用场景上有很大的区别。本文将详细介绍堆和栈的特点、区别以及各自的使用场景。php中文网给大家带来了相关的教程以及文章欢迎大家前来学习阅读。

2023.08.10

2668

6

线程和进程的区别
线程和进程的区别

线程和进程的区别:线程是进程的一部分,用于实现并发和并行操作,而线程共享进程的资源,通信更方便快捷,切换开销较小。本专题为大家提供线程和进程区别相关的各种文章、以及下载和课程。

2023.08.10

4518

6

windows查看端口占用情况
windows查看端口占用情况

Windows端口可以认为是计算机与外界通讯交流的出入口。逻辑意义上的端口一般是指TCP/IP协议中的端口,端口号的范围从0到65535,比如用于浏览网页服务的80端口,用于FTP服务的21端口等等。怎么查看windows端口占用情况呢?php中文网给大家带来了相关的教程以及文章,欢迎大家前来阅读学习。

2023.07.26

3339

3

查看端口占用情况windows
查看端口占用情况windows

端口占用是指与端口关联的软件占用端口而使得其他应用程序无法使用这些端口,端口占用问题是计算机系统编程领域的一个常见问题,端口占用的根本原因可能是操作系统的一些错误,服务器也可能会出现端口占用问题。php中文网给大家带来了相关的教程以及文章,欢迎大家前来学习阅读。

2023.07.27

2918

6

windows照片无法显示
windows照片无法显示

当我们尝试打开一张图片时,可能会出现一个错误提示,提示说"Windows照片查看器无法显示此图片,因为计算机上的可用内存不足",本专题为大家提供windows照片无法显示相关的文章,帮助大家解决该问题。

2023.08.01

1528

3

windows查看端口被占用的情况
windows查看端口被占用的情况

windows查看端口被占用的情况的方法:1、使用Windows自带的资源监视器;2、使用命令提示符查看端口信息;3、使用任务管理器查看占用端口的进程。本专题为大家提供windows查看端口被占用的情况的相关的文章、下载、课程内容,供大家免费下载体验。

2023.08.02

2659

5

windows无法访问共享电脑
windows无法访问共享电脑

在现代社会中,共享电脑是办公室和家庭的重要组成部分。然而,有时我们可能会遇到Windows无法访问共享电脑的问题。这个问题可能会导致数据无法共享,影响工作和生活的正常进行。php中文网给大家带来了相关的教程以及文章,欢迎大家前来阅读学习。

2023.08.08

3330

4

windows自动更新
windows自动更新

Windows操作系统的自动更新功能可以确保系统及时获取最新的补丁和安全更新,以提高系统的稳定性和安全性。然而,有时候我们可能希望暂时或永久地关闭Windows的自动更新功能。php中文网给大家带来了相关的教程以及文章,欢迎大家前来学习阅读。

2023.08.10

1677

3

热门下载

更多
网站特效
/
网站源码
/
网站素材
/
前端模板

精品课程

更多
相关推荐
/
热门推荐
/
最新课程
C++ Core Guidelines
C++ Core Guidelines

共0课时 | 0人学习

C++ Reference
C++ Reference

共0课时 | 0人学习

C++ 官方标准说明
C++ 官方标准说明

共0课时 | 0人学习