免责声明:我的答案是可能只与预WPF .NET(但相同的概念适用于这两种)。
您的标题问题的答案是“两个”。 System.Drawing
命名空间包含一个便利的Bitmap
类,它本质上是一个DIB(或设备无关位图)。 Bitmap
类包括一个GetHbitmap
方法,该方法创建原始DIB的内存副本的DDB(或设备相关位图)并返回句柄。
的DDB处理可以被选择到设备上下文(它可以让你使用超高速BitBlt
API方法)。或者你可以永远不要创建一个DDB,并且用纯净的.Net(最好的方法,IMO)来完成所有的图形操作。 GetHbitmap
是一个相对危险的方法,因为您必须在返回的句柄上调用DeleteObject
以便在完成后释放其内存(这是我能想到的唯一示例.Net方法需要 a PInvoked API调用才能正常工作)。另外,由于该方法返回IntPtr
,程序员往往不会意识到,当它被称为操作系统时,必须挖掘出与原始.Net(DIB)位图大小相等的另一块内存。
所以答案是:.Net使用DIB,但如果需要可以使用DDB。或者更糟的是,当需要而不是时。实际上,我已经继承了多个.NET Web应用程序,该应用程序使用GetHBitmap
而没有匹配DeleteObject
调用,产生一个长内存泄漏。
然而,您有一个更广泛的问题:运行在服务器上的.Net应用程序能否可靠地处理大量大型图像文件而不会导致服务器崩溃?答案是肯定的,只要你真的了解.NET框架在图像处理的背后做了什么。 .NET图形类封装了很多离开程序员的可怕细节,并且有些方法很糟糕,因为它使得程序员不太可能知道实际发生了什么。
编辑:忘了,包括从MSDN这一重要声明:
注意的System.Drawing中 命名空间内
类不支持Windows或ASP中使用 。 NET服务。 试图在这些应用程序类型 之一中使用来自 的这些类可能会产生意外问题,例如 由于运行时异常而导致服务性能降低和 。
翻译:“你可能会搞砸了 - 不要说我们没有警告你”。这基本上是合理的建议,因为这些课程虽然非常强大和有用,但也很危险。消耗一些资源并且无法正确释放它,或者以导致大量内存消耗的方式使用这些类是非常容易的。有时这些问题在桌面应用程序中并不是很大,但是在同时提供多个请求的高负载Web服务器中,这可能会成为一个巨大的问题。
但是,我认为它们可以在这种情况下安全地使用,或者说它有点不同,我认为如果您尝试处理大量可调整的位图一个Web服务器在同一时间。但是,我会确保在投入生产之前对我的网站代码进行了严格的负载测试。
更新1:下面引用(与link)适用于位图在.NET Compact Framework
,我不认为它适用于完整的框架(我主要包括在这里作一般参考 - 即这样我就可以有一天我会再次找到它):
这里有一点关于 的更深一点的信息[.NetCF]位图可能会被分配。 分配有两条主要路径,可能会影响分配内存的位置,但最后 与上面指示的 有相同的问题。
- 位流构造函数,将流 作为参数[即从文件加载]
- 这将构造一个DIB
- 的DIB被分配了应用进程的虚拟内存 (VM)的地址空间
- 位图构造器 ,需要一个高度/宽度的 参数
- 这将构造一个DDB
- DDBS由驱动程序分配的,典型地,在专用视频RAM中的gwes.exe或可能的 。这将使 实际使用的物理和虚拟 内存不在进程VM 空间中。
总之,我们有2种不同类型的 位图中我们用不同的 性能和分配 特性运行。 DDBS通常 可以更快地处理和绘制到 屏幕比的DIB,但它们是在外部存储器空间 可以引起分配 混乱并导致的 呼叫LockBits或保存性能是 较慢构造 。如果需要DIB,并且您希望根据宽度 和高度构建DIB,则我们提供一个函数,该函数可以构造一个宽度为 的位图,并指定像素格式。 此功能将构建DIB 而不是DDB。
的更多信息(还只是.NetCF位图)位置:
http://blog.opennetcf.com/ctacke/PermaLink,guid,987041fc-2e13-4bab-930a-f79021225b74.aspx
更新2:相关的完整的框架.NET位图(在底部摘要)一些链接:
http://www.dotnetmonster.com/Uwe/Forum.aspx/dotnet-performance/1187/Graphics-FromImage-Process-memory-usage
http://www.netframeworkdev.com/common-language-runtime/memory-issues-with-systemdrawingbitmap-30879.shtml
http://www.west-wind.com/WebLog/posts/8230.aspx
http://www.tech-archive.net/Archive/DotNet/microsoft.public.dotnet.framework.drawing/2005-06/msg00171.html
摘要:我觉得这个问题很难回答,因为,基本上,这(通过Bitmap
使用的内存的实际位置)是一个内部的.NET实现细节,大多没有证据是有原因的。由于看起来你不能确定位图的记忆现在在哪里,而且你肯定不能确定将来会在哪里生活,所以我不得不说MSDN在他们说的时候可能不是在开玩笑:
注意的System.Drawing中 命名空间内
类不支持Windows或ASP.NET服务中使用 。 试图在这些应用程序类型 之一中使用来自 的这些类可能会产生意外问题,例如 由于运行时异常而导致服务性能降低和 。
你可以引用你的参考资料,了解.Net如何管理图像?我无法找到这些信息,但它必须在某处可用。我想了解更多。 – Brian 2010-05-09 03:33:25
“或者你可以永远不要创建一个DDB,并且用纯净的.Net(最好的方法,IMO)来完成所有的图形操作。” - 安全但是s ................. l ........................... o ................... w – 2010-05-10 01:12:24
只是为了澄清,这意味着s ................ l .... ...............Ø.................... W上。 – 2010-05-10 01:12:52