我有一个图像编辑程序。许多编辑器操作都需要在内存中复制图像。图像可能非常大,编辑可以在几秒钟内完成几次,因此内存使用量很大。
我准确地Dispose()
每个未使用的图片。但是当我描述我的应用程序时,我注意到在强烈的编辑操作期间内存消耗增长(我甚至几次OutOfMemoryException
)。经过几秒钟的不活动后,它会返回常规值,因此没有内存泄漏。所以我认为原因是垃圾收集很少发生。我在每次编辑操作后都放了GC.Collect()
并且它有所帮助,现在内存消耗稳定。
但我不知道这是不是一个好方法?根据MSDN:
可以通过调用Collect强制进行垃圾收集,但大多数情况下,应该避免这种情况,因为它可能会产生性能问题。
我不需要收集应用程序中的所有内容,但只会破坏多个对象(Bitmap
' s)。我可以告诉GC只收集这些对象吗?或者可能有另一种方法来优化这个过程?
答案 0 :(得分:3)
与垃圾收集器混淆总是很棘手,几乎在所有情况下都应该避免。
从性能角度来看,最好的方法是尽可能避免通过重用对象和缓冲区来尽可能地使用GC。如果可能的话,这通常会以增加复杂性为代价,因此这是一种权衡。
否则建议的方法是设计您的应用程序以使GC更容易:
由于我怀疑你已经这样做了,剩下的就是彻底的性能测试。如果您不经常发布一些大型对象,因此GC难以预测,间隔并且您可以显示您的应用程序执行得更好(无论这意味着什么),如果您调用GC.Collect(),那么请继续。
据我所知,您无法控制GC收集的内容。在调用GC.Collect()时,如果它们已经进入GC第1代或第2代,你甚至无法确定它是否会收集刚发布的大对象。这就是为什么你必须测试和测量你的特定用例。< / p>
一个问题是,对于您的应用程序来说,实际上是否需要几秒钟才能让GC赶上并减少内存使用量?
答案 1 :(得分:1)
如果你可以对任何实现IDispose的东西使用'使用',那就去做吧。另一种方法是,您的计划组织严密,无法令人遗憾地管理流程。
你应该尽可能让框架管理处理。
问自己的问题:
我是否在创建对象的新实例而不是重用现有的?
使用后我可以将任何对象设置为null吗?或完全处理它们?
导致泄漏的是什么线?我建议运行程序和 切换任务管理员 - 然后单步执行 - 你会看到斜坡进入 在您单步执行时实时使用。
我可以批量生产吗?如果我管理100张图片,我可以分成10组 10?
答案 2 :(得分:0)
你可以使用&#39;使用&#39;这个过程的范围。
using(var bmp = new Bitmap(image))
{
/// your code
}