Graphics 系统内存不足异常。在Windows服务中绘图

Graphics 系统内存不足异常。在Windows服务中绘图,graphics,memory-management,windows-services,drawing,system.drawing,Graphics,Memory Management,Windows Services,Drawing,System.drawing,在windows服务中使用system.drawing时出现内存不足异常 以下是我代码的一部分: FileStream fs = new FileStream(ImagePath, FileMode.Open, FileAccess.Read); img = (Image)Image.FromStream(fs).Clone(); 异常不仅在这一点上出现,有时在涉及绘图、裁剪、调整大小和图像复制的其他点上也会出现 我总是处理所有用过的东西 我在system.drawing中看到了这篇关于“内存

在windows服务中使用system.drawing时出现内存不足异常

以下是我代码的一部分:

FileStream fs = new FileStream(ImagePath, FileMode.Open, FileAccess.Read);
img = (Image)Image.FromStream(fs).Clone();
异常不仅在这一点上出现,有时在涉及绘图、裁剪、调整大小和图像复制的其他点上也会出现

我总是处理所有用过的东西

我在system.drawing中看到了这篇关于“内存不足异常”的文章

虽然它与我的情况非常相似,但它是不同的,因为我的测试数据是一个由40个图像组成的重复链,因此如果其中一个图像中存在问题,它应该从第一个周期开始快速出现

我看到了上面提到的限制

它说我们不应该在Win/Web服务上使用system.drawing


好的,我需要将它与windows服务一起用于海量图像处理,如果有的话,还有哪些替代方案?

为什么要克隆图像?在您的示例中,您正在从文件中读取数据,然后创建副本。在具有高对象吞吐量的服务中抛出内存不足异常并不需要太多

您可以简单地执行以下操作:

var img = Image.FromFile(ImagePath);

您使用的内存太多,速度太快,可能没有尽快释放它

您需要对代码进行重构,以更加保守地使用您的资源,并确保您对大型对象的持有时间不会超过所需的时间,并且您正在尽早处理IDisPobles


这个过程并不容易,在这样一个论坛上也无法完全回答

您正在调用的
Clone
对象的
Image
未被处理(您的代码中可能还有其他类似错误)。这些对象消耗的内存只有在运行终结器后才会释放,终结器至少需要2个GC周期,并且
OutOfMemoryException
很可能会在第一个GC上抛出。
正确处理它应该类似于以下内容:

FileStream fs = new FileStream(ImagePath, FileMode.Open, FileAccess.Read);
using(var tmp = Image.FromStream(fs))
  img = (Image)tmp.Clone();
// dispose fs an img after use like usually

或者,您可以将整个文件读入
内存流
,并将其传递给
图像。FromStream
-这意味着图像不会被解析两次,这将节省额外的资源。

这可能不相关,但

我在C++中使用位图时遇到了问题,从较低级别的Windows API中排除了资源错误。这似乎是由于windows内部资源堆在使用BitBLT等绘制时无法处理/分配位图/位图部分造成的


我不知道这样的事情是否会让dotnet库绊倒。MSDN上的某个地方有一个安装设备驱动程序的工具,可以用来检查各种桌面堆(不知道这与服务有什么关系。)我想(我使用它已经有一段时间了)它显示了使用/可用的百分比,而这可能是某种指标,我怀疑这些区域的碎片也可能导致错误-不幸的是,我无法完全消除我的问题,但该工具可能会帮助您诊断您的问题。(看起来该工具可能被称为“dheapmon”。

我正在处理该代码之后的流,如果我不克隆它,则处理该流也会使图像为空。我不能使用Image.FromFile,因为它在整个处理过程中保存文件,这意味着在处理过程中不能移动或删除文件,这在我的情况下是不可接受的。好的一点,我训练有素的头脑很难想象这样的事情会发生。:)你是说那个叫“img”的物体???我在处理完后处理它。我还在处理这个代码之后的流。如果我不调用clone(),则处理流将使图像为空。检查我之前发布的这个问题:我是指由
FromStream(fs)
调用创建的对象(您正在克隆的对象)-处理流不会处理创建的
Image
对象。我在性能计数器或任务管理器中看不到那么多内存使用,是的,我正在使用大量内存,但我认为它的大小不足以导致此异常,除非system.drawing类使用的内存比预期的要多。您使用的内存不多,但会出现OOM异常。这里有些不对劲。没有什么奇怪的事情发生;操作系统的这些部分(本机绘图代码)和CLR/GC没有bug。你需要放弃所有的假设,从零开始,对每件事进行三次检查。哦,任务经理真差劲。至少从Sysinternal中获取Process Explorer,并使用性能计数器和Aaah,但没有做到这一点。我看到了“任务经理”,立刻怒不可遏。我的坏。@Will:这些组件的错误->异常转换肯定有问题,它们会抛出OfMemoryException来处理各种非内存错误。我编写了一个使用System.Drawing的windows服务,没有任何问题。建议禁止的原因仅在您正在桌面上绘图时。。。换句话说,Windows服务不应尝试绘制到屏幕上,因为Windows服务不一定有登录用户,因此没有可绘制到的桌面。事实上,MSDN中解释说,您“可以”在Windows服务中使用system.drawing,但它们不保证其行为。我的服务运行了几个小时没有任何问题,处理了数千张图像,但随后出现了此异常。