在单个app实例中加载大量位图时WPF内存不足exception。 有限制吗?

我需要将大量的位图加载到内存中以便在WPF应用程序中显示(使用.net 4.0)。 我遇到麻烦的地方是当我接近大约1,400MB的内存时(我从任务管理器的进程列表中得到这个)。

无论应用程序是在具有4GB内存还是6GB的计算机上运行(以及其他一些我没有详细信息的配置),都会发生同样的事情。 通过减少加载的图像和在1台机器上工作时很容易进行测试,然后它可以对它们进行全部工作,但是当它在一台机器上崩溃时它也可以在所有机器上运行。

当我减少图像数量并允许应用程序加载而不会导致内存exception时,我可以运行应用程序的多个实例(超过单个实例的1.4GB)而没有问题所以它似乎是每个实例限制或每个实例我的错误。

我将图像加载为BitmapImage,它们或者存储在List或者加载到List中,稍后在一堆分层序列中使用它们(使用Writeablebitmap

当我在使用中加载图像时发生错误。 在可重复的情况下,我加载了600个640X640图像以及另外200-300个较小的图像,范围从100X100到200X200,尽管它似乎是一个整体位计数问题。

所以我的问题是:

*在这种情况下,是否有一些内置的进程内存限制?

*是否有更好的技术将大量图像数据加载到内存中?

谢谢,Brian

是的,每个进程内存分配有一个限制。 其中一个解决方案是使您的二进制LARGEADDRESSAWARE耗尽更多内存。

请参考内存不足? 简单的方法来增加程序可用的内存 ,它围绕解决方案进行了很好的讨论。

以下可能是一个原因,但我不确定

问题不在于加载大量数据,而是因为CLR为大于85k内存的对象维护了一个大堆,并且你没有任何控制来释放这个大堆。

并且这些对象变为Long Lived,并且在Appdomain Unloads时通常会释放。

我建议尝试在另一个AppDomain中加载更大的图像,并使用该appdomain来处理更大的图像。

请参阅此MSDN Entry to Profiling GC

查看内存映射文件是否有助于您使用.net 4.0

还有更多例子

x86版本可以在64位Windows上访问4 GB,因此这是该过程的理论上限。 这要求应用程序具有大的地址感知能力 。 此外,.NET对单个对象施加了2 GB的限制。

您可能患有LOH碎片。 大于85000字节的对象存储在Large Object Heap中,这是托管堆的一个特殊部分,不会被压缩。

你说图像是600×600,但像素格式是什么,还有面具吗? 如果每个颜色通道使用一个字节加上alpha通道的一个字节,则每个图像为600x600x32,因此在32位进程中尝试一次加载600个将是一个问题。

您遇到了限制32位进程,只能访问大约2Gb的数据。 如果你要运行64位,你就不会有问题。 有许多方法可以解决这个问题,其中一些方法是:

  • 只需不加载那么多数据,只在需要时加载。 使用缓存。
  • 使用内存映射文件将整个数据块映射到内存中。 不推荐,因为您必须自己进行所有内存管理。
  • 使用多个进程来保存数据并使用IPC机制仅提供所需的数据,类似于第1项。