【问题标题】:MemoryMappedFiles: How much memory can be allocated for filesMemoryMappedFiles:可以为文件分配多少内存
【发布时间】:2011-07-27 22:43:56
【问题描述】:

我的 CT 原始数据文件很大,最大可能超过 20 到 30GB。对于我们部门当前的大多数计算机,我们最多只有 3GB。但是为了处理数据,我们需要遍历所有可用数据。当然,我们可以通过 read 和 write 函数顺序遍历数据来做到这一点。但有时需要在内存中保留一些数据。

目前我有自己的内存管理,我创建了一个所谓的 MappableObject。每个 rawdatafile 包含 20000 个结构,每个结构都显示不同的数据。每个 MappableObject 都指向文件中的一个位置。

在 C# 中,我创建了一个部分工作的机制,如果需要,它会自动对数据进行 mps 和取消映射。几年前我就知道 MemoryMappedFiles,但在 .NET 3.5 中我拒绝使用它,因为我知道在 .NET 4.0 中它会原生可用。

所以今天我尝试了 MemoryMappedFiles,发现无法分配所需的内存。如果我有一个 32 位系统,并且我想分配 20GB,由于超出了逻辑地址空间的大小,它不起作用。这对我来说很清楚。

但是有没有办法像我一样处理这么大的文件?我还有什么机会?你们是怎么解决这些问题的?

谢谢 马丁

【问题讨论】:

    标签: c# memory memory-management dynamic-memory-allocation


    【解决方案1】:

    我知道的唯一限制是您可以映射的文件的最大视图的大小,它受地址空间的限制。内存映射文件可以大于地址空间。 Windows 需要在进程地址空间的连续块中映射文件视图,因此最大映射的大小等于最大可用地址空间块的大小。文件总大小的唯一限制是文件系统本身。

    看看这篇文章:Working with Large Memory-Mapped Files

    【讨论】:

      【解决方案2】:

      “内存映射”,您不能将 20 GB 映射到 2 GB 的虚拟地址空间。在 32 位操作系统上获得 500 MB 是很棘手的。请注意,除非您需要大量随机访问文件数据,否则它不是一个好的解决方案。当您必须对视图进行分区时,这应该很困难。通过常规文件的顺序访问是无与伦比的,内存使用量非常小。还要注意从 MMF 封送数据的成本,您仍在为托管结构的副本支付费用封送成本。

      【讨论】:

      • 这是一个我必须考虑的好建议。事实上,在大多数情况下,我可以按顺序运行数据。但也有很多情况我需要随机访问。当我需要框架方面的东西时,我完全无法预测。
      【解决方案3】:

      你仍然可以顺序读取文件,只是不能在内存中存储超过 2GB 的数据。

      您可以一次映射文件的块,最好是结构的倍数。

      例如。文件为 32GB。一次内存映射 32MB 的文件并解析它。到达这 32MB 的末尾后,映射文件的下一个 32MB 并继续,直到到达文件的末尾。

      我不确定最佳映射大小是多少,但这是一个示例。

      【讨论】:

        【解决方案4】:

        你们都是对的。我首先尝试的是使用没有文件的内存映射文件。在那里它不起作用。如果我有一个现有文件。我可以映射尽可能多的内存。我想在没有真实现有文件的情况下使用 MemoryMappedFiles 的原因是它应该在流被处理时自动删除。 MemoryMappedFile 不支持此功能。

        我现在看到的是,我可以执行以下操作来获得预期的结果:

               // Create the stream
                FileStream stream = new FileStream(
                    "D:\\test.dat", 
                    FileMode.Create, 
                    FileAccess.ReadWrite, 
                    FileShare.ReadWrite, 
                    8, 
                    FileOptions.DeleteOnClose // This is the necessary part for me.
                    );
        
                // Create a file mapping
                MemoryMappedFile x = MemoryMappedFile.CreateFromFile(
                    stream,
                    "File1", 
                    10000000000, 
                    MemoryMappedFileAccess.ReadWrite, 
                    new MemoryMappedFileSecurity(),
                    System.IO.HandleInheritability.None, 
                    false
                    );
        
                // Dispose the stream, using the FileOptions.DeleteOnClose the file is gone now
                stream.Dispose();
        

        至少在查看第一个结果时,它对我来说看起来不错。

        谢谢。

        【讨论】:

          猜你喜欢
          • 2014-03-02
          • 2020-03-12
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2011-08-27
          相关资源
          最近更新 更多