C# .NET应用程序中的大内存块。什么';如何以最佳/推荐/可扩展的方式处理这些问题?

C# .NET应用程序中的大内存块。什么';如何以最佳/推荐/可扩展的方式处理这些问题?,c#,optimization,memory-management,large-files,C#,Optimization,Memory Management,Large Files,设想一个应用程序通过合并和/或编辑其他文件来创建大型文件。 例如,一个应用程序: 打开图像存档 添加或替换某些图像 更改现有图像的某些部分 使用生成的图像集创建新存档 可以按任何顺序添加/替换/更改图像,因此直到执行结束时才能创建新的存档 天真的方法是为原始存档中的每个图像创建一组MemoryStream对象,然后在需要时更改/删除/替换流,然后将该集写入新存档。就执行速度而言,这种方法可能会给出最佳结果 问题很明显:没有足够的内存来保存流集 在这种情况下,你有什么建议 我想我应该用一些速度

设想一个应用程序通过合并和/或编辑其他文件来创建大型文件。 例如,一个应用程序:

  • 打开图像存档
  • 添加或替换某些图像
  • 更改现有图像的某些部分
  • 使用生成的图像集创建新存档
可以按任何顺序添加/替换/更改图像,因此直到执行结束时才能创建新的存档

天真的方法是为原始存档中的每个图像创建一组
MemoryStream
对象,然后在需要时更改/删除/替换流,然后将该集写入新存档。就执行速度而言,这种方法可能会给出最佳结果

问题很明显:没有足够的内存来保存流集

在这种情况下,你有什么建议

我想我应该用一些速度来换取内存,并使用一些临时的非内存存储。不过,我不知道该用什么


我应该使用内存映射文件吗?还是普通的旧临时文件,有创建和删除它们的机制?也许还有别的吗?

您可以使用
文件流
,并以与
内存流
相同的方式使用它。它本质上把确定缓冲以及所有这些的负担都放在了操作系统上。操作系统确实知道得最好,它让驱动程序和硬件处理缓存和微调的复杂问题。只需编写易于理解的代码,并配置文件,配置文件,配置文件

如果分析显示需要,您可能可以将这两种类型的流混合使用,以获得性能良好、外观良好的流

我应该使用内存映射文件吗


这肯定是我想到的第一件事。这种方法的唯一问题是,文件大小最终是否会占用所有映射空间。

一种方法是使用文件和文件系统(大部分)并提供某种内存缓存或映射

如果您处理的是大量或相当大的文件,那么您就无法真正将其与内存大小匹配(或者在内存中解压完整的归档文件),除非我们讨论的是额外的h/w、RAM

具体地说,我个人会选择像

class MemoryArchive {}  
…它冒充您的前端文件,在后端存档

您可以将归档文件解压缩到磁盘的temp files文件夹中,就像大多数解压util一样,然后处理“较小的访问单元”,即文件

您的
MemoryArchive
基本上就像内存中的所有内容一样,因此您需要将内存流(或您决定在对象级别直接访问的任何内容)映射到磁盘上的临时文件,即文件流

可能还有一些处理同步和/或错误、问题的健壮方法,因为您需要确保内存中的内容与磁盘上的内容同步,并保持“集成”完好无损

在这一点上(并且取决于系统的性质等),主要任务可能是围绕文件系统存储对某种事务进行编码,这正是您开始类似于数据库管理系统的地方。但这是另一个“天平的末端”——如果你可以没有它生活,并保持它的简单,它可能不会有那么大的问题

只是一个想法,不过这取决于你的具体细节-
i、 e.事物的规模(可能会有很大的变化,例如,如果内存允许,在某些情况下,您可以加载,并且处理速度足够快),归档中的“小更改”与归档的大小,更改的频率和性质

在最简单的情况下,我会将东西存储为临时文件,并根据需要处理较小的增量更改

拥有某种
MemoryArchive
会给你一个未来的篱笆-因此你可以改变这一点,或者根据档案的大小等混合使用几种方法。实际上,在这些情况下,一些“混合方法”通常是最好的,因为在处理不同的文件、大小时,很难找到“一刀切”的解决方案


希望这有帮助,

首先,请注意,基本上对于LOH对象,内存不会进行碎片整理,因此,如果您连续创建和处理大量大型对象,您“很可能”会出现“内存不足异常”,因为碎片化的内存孔可能不会给您足够大的连续内存空间(.net 4.5及以上版本对此进行了一定程度的优化,但问题仍然存在)。因此,要回答您的问题,很大程度上取决于您的机箱的体系结构。如果它是一个64位且具有足够的RAM,并且您知道您的文件将正好适合LOH问题,请务必使用内存中的对象,否则正如Michael所建议的那样,将不可避免地发生文件流震荡。

您有任何性能要求吗?我很乐意ed选择普通临时文件(可能存储在嵌套结构中,以避免许多小文件的速度减慢)从这里开始。如果你躲在合适的界面后面,你以后可以随时改变主意!你考虑过使用Microsoft的Esent吗?Wiki页面:Esent托管的.Net lib:@JeffFoster当然,我希望尽可能保持速度。除此之外,我没有特殊的性能要求。@YS。我以前从未听说过这一点。谢谢,我会看一看。这基本上是普通的旧临时文件,对吗?我也会尝试它们。@Bobrovsky是的,差不多。基于您的分析结果的混合可能最适合您,并给您一个特别调整的结果。我需要处理许多文件。甚至可能有数千个。谢谢您的警告,我会问goog关于映射的空间限制。谢谢你关于LOH限制的警告。我想我已经看到了后果