You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

仅写入场景下内存映射文件出现不必要读取的问题排查

内存映射文件写入操作中的异常IRP请求问题

我开发了一个仅向内存映射文件(Memory Mapped File)写入数据的简单应用:通过循环将50块大小为4096*100字节的数组写入内存映射文件对应的内存区域。由于仅执行写入操作,我预期不会产生读取IRP请求,但实际出现了20个读取IRP(总量与写入内存相当,且为扇区大小的倍数),而写入操作仅触发1次。

有趣的是,即使文件标记了DeleteOnClose且系统内存充足,写入操作仍被执行——按道理结果会被丢弃,本无需执行写入。这可能是.NET内存映射文件的实现问题。

我对这些不必要的读取操作感到困扰,目前关于内存映射文件的资料较少,相关问题的解答也寥寥无几,希望有人能指引我获取更多内存映射文件的相关资料。

更新1

我目前正在自行实现文件映射,未使用内存映射文件:当文件是全新分配时,我直接分配内存,明确该内存从未被写入过。我期望MMF(内存映射文件)也能有类似的表现。

测试代码

using System;
using System.IO;
using System.IO.MemoryMappedFiles;

namespace MemoryMappedFileTest
{
    class Program
    {
        // Size of a single block in bytes
        const int SizeOfBlock = 4096 * 100;

        // Number of blocks.
        const int NoOfBlocks = 50;

        // Name of the test file.
        const string FileName = "E:\\MMF\\mm.dat";

        static unsafe void Main(string[] args)
        {
            // Create the temporary which is deleted on close.
            using var stream = new FileStream(FileName, FileMode.CreateNew, FileAccess.ReadWrite, FileShare.ReadWrite, 4096, FileOptions.DeleteOnClose);

            // Create the file mapping and the view
            using var mm = MemoryMappedFile.CreateFromFile(stream, null, NoOfBlocks * (long)SizeOfBlock, MemoryMappedFileAccess.ReadWrite, HandleInheritability.None, false);
            using var va = mm.CreateViewAccessor();

            // Get the absolute start address
            var StartAddress = va.SafeMemoryMappedViewHandle.DangerousGetHandle();

            // Create some empty block data we can write.
            var BlockData = new byte[SizeOfBlock];

            // Run through the blocks and write 0s in it.
            for (int blockNo = 0; blockNo < NoOfBlocks; blockNo++)
            {
                // Get the address of the block
                byte* blockAddress = (byte*)StartAddress + checked(blockNo * (long)SizeOfBlock);

                // Work with spans
                Span<byte> blockSpan = new(blockAddress, SizeOfBlock);
                for (int i = 0; i < SizeOfBlock; i++)
                    blockSpan[i] = 0;
                //BlockData.CopyTo(blockSpan);

                // Print the blockNo.
                Console.WriteLine(blockNo);
            };

            Console.WriteLine("Done");

            stream.Dispose();
        }
    }
}

内容的提问来源于stack exchange,提问作者msedi

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.06 23:50:26