简体   繁体   English

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

[英]WPF out of memory exception when loading large amount of bitmaps in single instance of app. Is there a limit?

I need to load large amounts of bitmaps into memory for display in a WPF app (using .net 4.0). 我需要将大量位图加载到内存中以便在WPF应用程序中显示(使用.net 4.0)。 Where I run into trouble is when I approach around 1,400MB of memory ( I am getting this from the process list in the task manager). 我遇到麻烦的地方是当我接近大约1,400MB的内存时(我从任务管理器的进程列表中得到这个)。

This same thing happens whether the app is run on a machine with 4GB of memory or 6GB (and some other configs that I do not have the details on). 无论应用程序是在具有4GB内存还是6GB的计算机上运行(以及其他一些我没有详细说明的配置),都会发生同样的事情。 It is easy to test by reducing the images loaded and when it works on 1 machine then it works on them all, but when it crashes on one it also does on all. 通过减少加载的图像以及它在1台机器上工作时很容易进行测试,然后它可以对它们进行全部工作,但是当它在一台机器上崩溃时它也可以在所有机器上运行。

When I reduce the image count and allow the app to load without causing the memory exception I can run multiple instances of the app (exceeding the 1.4GB of the single instance) without the problem so it appears to be some per instance limit or per instance error on my part. 当我减少图像数量并允许应用程序加载而不会导致内存异常时,我可以运行应用程序的多个实例(超过单个实例的1.4GB)而没有问题所以它似乎是每个实例限制或每个实例我的错误。

I load the images as a BitmapImage and they are either stored in a List<BitmapImage> or loaded into a List<byte[]> where they are later used in a bunch of layered sequences (using a Writeablebitmap ) 我将图像作为BitmapImage加载,它们或者存储在List<BitmapImage>或者加载到List<byte[]>中,稍后在一堆分层序列中使用它们(使用Writeablebitmap

The error occurrs when I load the images not while in use. 当我在使用中加载图像时发生错误。 In the repeatable case I load 600 640X640 images plus another 200-300 smaller images ranging from 100X100 to 200X200, although it appears to be an overall bit count that is the problem. 在可重复的情况下,我加载了600个640X640图像以及另外200-300个较小的图像,范围从100X100到200X200,尽管它似乎是一个整体位计数问题。

So my questions are: 所以我的问题是:

*Is there some built in per process memory limit in a situation like this? *在这种情况下,是否有一些内置的进程内存限制?

*Is there a better technique to load large amounts of image data into memory? *是否有更好的技术将大量图像数据加载到内存中?

Thanks, Brian 谢谢,Brian

Yes, there is a limit on per process memory allocations. 是的,每个进程内存分配有一个限制。 One of the solutions is to make your binary LARGEADDRESSAWARE to use up more memory. 其中一个解决方案是使您的二进制LARGEADDRESSAWARE耗尽更多内存。

Refer Out of memory? 请参考内存不足? Easy ways to increase the memory available to your program , it has great discussion around solutions to this. 增加程序可用内存的简便方法 ,它围绕解决方案进行了很好的讨论。

Below may be a cause but i am not sure 以下可能是一个原因,但我不确定

Problem is not about loading large amout of data but because CLR maintains a Large Heap for object greater than 85k of memory and you don't have any control to free this large heap. 问题不在于加载大量数据,而是因为CLR为大于85k内存的对象维护了一个大堆,并且你没有任何控制来释放这个大堆。

and these objects became Long Lived and will normally deallocated when Appdomain Unloads. 并且这些对象变为Long Lived,并且在Appdomain Unloads时通常会释放。

i would suggest that try to load larger images in another AppDomain and use that appdomain to manupulate larger images. 我建议尝试在另一个AppDomain中加载更大的图像,并使用该appdomain来处理更大的图像。

See this MSDN Entry to Profiling GC 请参阅此MSDN Entry to Profiling GC

See if Memory Mapped Files helps in case you are using .net 4.0 如果使用.net 4.0,请查看内存映射文件是否有帮助

And more example 还有更多的例子

A x86 build can access 4 GB on 64 bit Windows, so that's the theoretical upper limit for the process. x86构建可以在64位Windows上访问4 GB,因此这是该过程的理论上限。 This requires the application to be large address aware . 这要求应用程序具有大地址感知能力 Additionally .NET imposes a 2 GB limit on a single object. 此外,.NET对单个对象施加了2 GB的限制。

You may be suffering from LOH fragmentation. 您可能患有LOH碎片。 Objects larger than 85000 bytes are stored on the Large Object Heap, which is a special part of the managed heap that doesn't get compacted. 大对象堆上存储的对象大于85000字节,这是托管堆的一个特殊部分,不会被压缩。

You say that the images are 600x600, but what is the pixel format and is there a mask as well? 你说图像是600x600,但像素格式是什么,还有面具吗? If you use a byte per color channel plus a byte for the alpha channel each picture is 600x600x32, so trying to load 600 of them at once will be a problem in a 32 bit process. 如果每个颜色通道使用一个字节加上alpha通道的一个字节,则每个图像为600x600x32,因此在32位进程中尝试一次加载600个将是一个问题。

You're running into the limitation 32 bit processes which can only access about 2Gb of data. 您遇到了限制32位进程,只能访问大约2Gb的数据。 If you were to run 64 bit you wouldn't have the issues. 如果你要运行64位,你就不会有问题。 There are a number of ways to work around the issue, some of which are: 有很多方法可以解决这个问题,其中一些方法是:

  • Simply don't load that much data, load only when needed. 只需不加载那么多数据,只在需要时加载。 Use caching. 使用缓存。
  • Use memory mapped files to map whole chucks of data into memory. 使用内存映射文件将整个数据块映射到内存中。 Not recommended as you'll have to do all the memory management yourself. 不推荐,因为您必须自己进行所有内存管理。
  • Use multiple processes to hold the data and use an IPC mechanism to only bring over the data you need, similar to item 1. 使用多个进程来保存数据并使用IPC机制仅提供所需的数据,类似于第1项。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM