我需要将大量位图加载到内存中以便在WPF应用程序中显示(使用.net 4.0)。我遇到麻烦的地方是当我接近大约1,400MB的内存时(我从任务管理器的进程列表中得到这个)。
同样的事情发生在应用程序是在具有4GB内存还是6GB的计算机上运行(以及其他一些我没有详细信息的配置)。通过减少加载的图像以及它在1台机器上工作时很容易进行测试,然后它可以对它们进行全部工作,但是当它在一台机器上崩溃时它也可以在所有机器上运行。
当我减少图像数量并允许加载应用程序而不会导致内存异常时,我可以运行应用程序的多个实例(超过单个实例的1.4GB)而没有问题所以它似乎是每个实例的一些限制或者我的实例错误。
我将图像加载为BitmapImage,它们存储在List<BitmapImage>
中或加载到List<byte[]>
中,稍后在一堆分层序列中使用它们(使用Writeablebitmap
)
当我在使用中加载图像时发生错误。在可重复的情况下,我加载了600个640X640图像以及另外200-300个较小的图像,范围从100X100到200X200,尽管它似乎是一个整体位数问题。
所以我的问题是:
*在这种情况下,是否有一些内置的进程内存限制?
*是否有更好的技术可以将大量图像数据加载到内存中?
谢谢, 布赖恩
答案 0 :(得分:11)
是的,每个进程内存分配都有一个限制。其中一个解决方案是让你的二进制LARGEADDRESSAWARE耗尽更多内存。
参考Out of memory? Easy ways to increase the memory available to your program,它就此解决方案进行了很好的讨论。
答案 1 :(得分:3)
下面可能是一个原因,但我不确定
问题不在于加载大量数据,而是因为CLR为大于85k内存的对象维护了一个大堆,并且你没有任何控制来释放这个大堆。
并且这些对象变为Long Lived,并且在Appdomain卸载时通常会解除分配。
我建议尝试在另一个AppDomain中加载更大的图像,并使用该appdomain来处理更大的图像。
See this MSDN Entry to Profiling GC
See if Memory Mapped Files helps in case you are using .net 4.0
答案 2 :(得分:1)
x86版本可以在64位Windows上访问4 GB,因此这是该过程的理论上限。这要求应用程序为large address aware。此外,.NET对单个对象施加了2 GB的限制。
您可能患有LOH碎片。大对象堆上存储的对象大于85000字节,这是托管堆的一个特殊部分,不会被压缩。
你说图像是600x600,但像素格式是什么,还有面具吗?如果每个颜色通道使用一个字节加上alpha通道的一个字节,则每个图像为600x600x32,因此在32位进程中尝试一次加载600个将是一个问题。
答案 3 :(得分:0)
您遇到限制32位进程,只能访问大约2Gb的数据。如果你要运行64位,你就不会有问题。 有很多方法可以解决这个问题,其中一些方法是: