我正在尝试使用内存映射文件访问大文件。在研究与标准 I/O 文件访问机制相比的性能时,我注意到了一个我目前无法解释的异常行为。
使用带有 MemoryMappedFileAccess.ReadWrite 标志的内存映射访问 3GB 大文件后,即使我只是在文件上打开 FileStream,也需要大约 9 秒才能再次打开该文件。使用 MemoryMappedFile 后下次访问文件会很慢。即使没有定义 ViewAccessors,也没有向文件写入任何内容,也会发生这种情况。如果我使用 Read 标志创建 MemoryMappedFile,则不会发生这种行为,下一次打开操作将只需要大约一毫秒。

我读到,在不再使用映射之前,脏页可能不会写入磁盘,但考虑到我没有向文件写入任何内容,并且该进程是唯一使用内存映射的进程,我不明白为什么仍然会发生这种情况。

我用这段代码测试过:

static void Main(string[] args)
{
    TestFileOpen();
    TestMMF();
    TestMMF();
    TestFileOpen();
    TestFileOpen();
    TestMMF();

    Console.WriteLine("Finished.");
    Console.ReadKey();
}

private static void TestMMF()
{
    Console.Write("Open Memory Mapped File... ");
    const long size = 1024L*1024L*3000L;

    Stopwatch sw = Stopwatch.StartNew();

    using (FileStream stream = new FileStream(filePath, FileMode.Open, FileAccess.ReadWrite, FileShare.ReadWrite))
    using (MemoryMappedFile.CreateFromFile(stream, "Map", size, MemoryMappedFileAccess.ReadWrite, null, HandleInheritability.None, true))
    {
    }

    Console.WriteLine(sw.Elapsed.TotalSeconds);
}

private static void TestFileOpen()
{
    Console.Write("Open File Stream...        ");

    Stopwatch sw = Stopwatch.StartNew();
    using (File.Open(filePath, FileMode.OpenOrCreate, FileAccess.ReadWrite, FileShare.ReadWrite))
    {
    }

    Console.WriteLine(sw.Elapsed.TotalSeconds);
}

这给了我:
Open File Stream...        9,2946138
Open Memory Mapped File... 0,0003105
Open Memory Mapped File... 9,2050714
Open File Stream...        9,2130051
Open File Stream...        0,0001751
Open Memory Mapped File... 0,0001529
Finished.

请注意,使用 FileStream 后的调用会很快,而使用 MemoryMappedFile 后的调用会花费很长时间。
另请注意,第一次调用也需要很长时间,这是因为基准程序中的最后一次调用(应用程序的前一次运行!)使用内存映射访问了文件。

我错过了什么吗?我可以做些什么来防止这种情况发生吗?

最佳答案

正如评论中所确定的,此延迟是由防病毒软件引起的。

关于c# - MemoryMappedFile 导致下一个 File.Open 需要很长时间,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/35340958/

10-10 13:47