使用大量内存的位图图像



我有一个应用程序,它从XML文件读取JPEG(到字节数组),生成MemoryStream并使用这些来实例化BitmapImages。JPEG的整个大小约为60 MB。但是,我的应用程序的内存使用量是1.6GB(之后会发生系统内存不足异常)。

我将字节数组、MemoryStream和(当然)BitmapImages保留在内存中。因此,我希望存储在内存中的大小大约是原始大小的三倍(也许更多),但1.6GB是荒谬的。

是什么原因造成的?

提前感谢您的帮助。

真的没那么荒谬。要记住的一个好的经验法则是,JPEG的平均大小约为保存为BMP的同一图像的10%。有些图像的可压缩性更强,有些图像的压缩性更低,JPEG编码器的质量和压缩设置也有很大的不同,但根据我的经验,这一原则通常适用。

如果我们在这种情况下接受该规则为真,那么您的程序仅存储至少720MB的图像数据;字节阵列中的60MB JPEG数据和MemoryStream中的60MBJPEG数据,以及600MB未压缩的BMP图像。此外,该程序还将自己和任何引用的第三方二进制文件加载到同一内存空间中(包括引用的Framework命名空间的DLL;人们经常忘记,Framework并不是"免费"使用的,因为它是"内置的"),并记住,某些集合以非常乐观的方式为自己请求内存;例如,每当达到List的内部最大容量时,它就会将自己的大小调整为以前的两倍。字典也做同样的事情,增加了维护两个内部数组结构的开销;一个用于键散列,另一个用于包含链接到键散列的实际值的"节点"。这种行为很容易导致处理大量对象集合的程序请求比运行时允许提供的内存更多的内存。然后,如果这是一个图形应用程序,运行时会为使用图形元素的每个线程维护一个消息循环,并挂接到每个图形元素(每个"窗口",尽管这个词用词不当,因为实际上所有GUI元素都是"窗口"而不仅仅是通常称为窗口的Form对象)。

所有这些都可以很容易地使应用程序需要1.6GB的托管内存。然后,当应用程序要求增加400MB的内存(以调整大型集合的大小),或要求超过21亿的新句柄(.NET即使在64位操作系统中也使用32位索引,因此运行时每个进程总共只能跟踪2个32不同的内存地址)时,运行时将注入OOME。

最新更新