繁体   English   中英

.NET图像类的内存使用情况和碎片:位图与图元文件

[英]The Memory Usage and Fragmentation of .NET Image classes: Bitmap vs. Metafile

由于看似过早的“内存不足”异常,我们一直在仔细研究各种.NET构造的内存使用情况……特别是倾向于使大型对象堆碎片化的大型对象,从而导致“内存不足”异常。 .NET Image类:位图和图元文件,这是一个令人惊讶的领域。

这是我们认为我们已经学到的内容,但是未能找到要验证的MS文档,因此,我们感谢其他人可以提供的任何确认:

(1)当您从压缩光栅文件(JPG,PNG,GIF等)创建位图对象时,它将以该文件的完整分辨率消耗完全未压缩的像素阵列的内存。 因此,例如,将9000x3000像素的5MB JPG扩展为9000x3000x3字节(假设24位颜色,没有alpha),或消耗的内存为81MB。 正确?

(1a)有证据(请参阅下面的2b)还存储了原始压缩格式...因此,在这种情况下实际上为86MB。 但这还不清楚……有人知道吗?

(2)创建图元文件对象然后在其中绘制光栅文件(JPG,PNG,GIF等)时,它仅消耗压缩文件的内存。 因此,如果将一个9000x3000像素的5MB JPG绘制到图元文件中,它将仅消耗大约5MB的内存。 正确?

(2a)要将栅格文件绘制到图元文件对象中,唯一的方法似乎是使用该文件加载位图,然后将位图绘制到图元文件中。 有没有更好的方法而不涉及临时加载大量位图数据(并导致相关的内存碎片)?

(2b)将位图绘制到图元文件中时,它使用的压缩格式的大小类似于原始压缩文件的大小。 它是通过将原始压缩文件存储在位图中来实现的吗? 还是通过使用原始压缩设置重新压缩扩展的位图来做到这一点?

(3)我们最初假设将大型(> 85KB)图像对象放置在大型对象堆中。 实际上,事实并非如此。 而是,每个位图和每个图元文件都是“小对象堆”中的24字节对象,它是指包含真实数据的本机内存块。 正确?

(3a)我们假设这样的本机内存就像大对象堆一样,因为它无法压缩...一旦将大对象放置到本机内存中,它就永远不会移动,因此本机内存的碎片会引起与大对象堆的碎片。 真正? 还是对底层位图/图元文件数据进行了更有效的特殊处理?

(3b)因此,似乎有四个独立的内存块是分别管理的,并且每个内存块用完都会导致相同的“内存不足”异常:小对象堆(受管理对象<85KB,由GC压缩),大对象对象堆(由GC收集但未压缩的大于85KB的托管对象),本机内存(非托管对象,可能未压缩)和台式机堆(在其中管理Windows句柄和此类有限资源)。 我是否已正确记录了这四个文件? 还有其他我们应该注意的吗?

任何人都可以提供的以上任何澄清将不胜感激。 如果有一本很好的书或文章能充分说明上述内容,请告诉我。 (我很乐意做必要的阅读;但是绝大多数书没有那么深入,因此不要告诉我任何我不知道的内容。)

谢谢!

有两种存储图像数据的方法:作为像素或向量。 Bitmap是关于像素的, Metafile是关于像素矢量的。 矢量数据的存储效率更高。

为了允许操作位图,必须将其数据未压缩地存储在内存中。 否则,对于每次更改, GetPixelSetPixel都必须解压缩,更改,重新压缩位图(如果这样做甚至有可能开始的话)。

图元文件是由Microsoft创建的,旨在与GDI一起使用,因此它可能包含一些内存效率更高的压缩算法,这些算法可直接与图形卡一起使用。 另外,图元文件没有GetPixel SetPixel方法,因此不必在内存中将其解压缩即可进行操作。


您不必关心运行时使用的内存池。 还有更多方法,运行时可以决定将对象放置在何处。 同样,您不应该担心使用(大)对象可能引起的内存不足异常。 运行时将尽其所能(将对象放入其他对象之间的间隙,压缩堆,扩展可用虚拟内存)以确保您不会遇到内存不足的异常。 如果您确实以某种方式得到了此类异常,则可能是代码中应解决的另一个问题(例如内存泄漏)。

内存堆,映射和表的概述:(

.NET中使用的堆,地图和表格


同样,您认为超过85 KiB的对象放置在大对象堆上的假设也不完全正确。 对于当前版本的CLR中的大多数对象,“是”是正确的,但例如,大型对象堆上还会分配一个8 KiB的双精度​​数组(1000个双精度数组)。 只需让运行时对此进行关注即可。

我知道其中一些答案:

(1)是的,这是位图图像的定义。

(3)是的,这就是为什么Bitmap实现IDisposable接口的原因。

(3a)这似乎令人惊讶。 完成对位图对象的处理后,是否正在它们上运行Dispose()方法?

(3b)至少这四个是。

暂无
暂无

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

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