MemoryMappedFile与很慢的CreateViewStream

本文关键字:CreateViewStream MemoryMappedFile | 更新日期: 2023-09-27 18:08:33

我使用的内存映射文件大约是。100gb的数据。当我在那个文件上调用CreateViewStream时,它需要30分钟来创建它,似乎是因为内存映射文件的大小,但是,为什么要花这么长时间?它是否将整个文件复制到托管内存中?

当我用文件流写入文件并在不重新启动的情况下访问它时,需要更长的时间。(奇怪的)

MemoryMappedFile与很慢的CreateViewStream

我无法复制这些问题。下面是我用来测试的代码:

    static void Main(string[] args)
    {
        var sw = Stopwatch.StartNew();
        var mmf = MemoryMappedFile.CreateFromFile(@"f:'test.bin");
        var stream = mmf.CreateViewStream();
        for (int i = 0; i < 100000; i++)
        {
            stream.ReadByte();
        }
        Console.WriteLine(sw.Elapsed);
    }

f:'test.bin是一个100GB的零填充文件,我为这个测试的目的而生成。我能够创建MemoryMappedFile,然后运行CreateViewStream并在3.7秒内从中读取100,000字节。

请提供显示您所描述的行为的示例代码,我很乐意将其分开,看看发生了什么。

如果不了解代码、主存和体系结构,这个问题很难回答。因此,我只能猜测一些重要的指针:

  1. 你的内存够吗?直接,如果您引用的地址尚未加载到RAM中,则会在后台发生页面错误,并为您将数据读取到RAM中。您的程序不会注意到此活动,因为在处理页面错误时线程被挂起。好文章。
  2. 同一篇文章中的另一个重要观点—您无法控制中有多少MMF保存在内存中或保存多长时间。这意味着使用MMF可能会将其他东西挤出RAM,例如"很快"需要返回的代码或数据页。从而导致较慢的执行。我特别想指出任何阅读这个答案的人在这里的另一个答案,这样我们就能清楚地知道慢在处理器周期方面有多慢。
  3. 接下来,创建一个流。适合顺序访问,而您可能试图随机读取/写入

关于FileStream与MMF方法中代码的端到端运行时间,我认为您应该重新运行测试,因为运行第一种方法可能会导致第二种方法的预热缓存。那么结果就不正确了。

根据MMF的MSDN文档,

内存映射文件使程序员能够处理非常大的文件文件,因为内存可以并发管理,并且它们允许对文件的完全随机访问,而不需要查找。

MMF的工作方式是将文件的整个(或一部分)映射为虚拟内存,当您访问文件的部分时,操作系统透明地将其调入和调出内存。这就是为什么mmf最适合处理大文件的原因。

您可以更聪明地读取整个文件的一部分,并通过使用:

执行随机访问
using (var accessor = mmf.CreateViewAccessor(offset, length))
{
    //Here you have access to a specific part of the file
}

,以便您可以访问具有指定偏移量和大小的视图,您的猛犸文件的内存映射

相关文章:
  • 没有找到相关文章