C# foreach循环中的垃圾收集器太慢?
我有一个foreach循环,在这里我对图像进行一些操作。当我用50多张图片运行这段代码时,我得到了一个C# foreach循环中的垃圾收集器太慢?,c#,foreach,garbage-collection,C#,Foreach,Garbage Collection,我有一个foreach循环,在这里我对图像进行一些操作。当我用50多张图片运行这段代码时,我得到了一个OutOfMemoryException;因为每个映像实例的大小为15+MB var files = Directory.GetFiles(path).ToList(); foreach (var file in files) { Image image = new Bitmap(file); //Do some operations } 我删除了主逻辑,因为这段代码仍然存
OutOfMemoryException
;因为每个映像实例的大小为15+MB
var files = Directory.GetFiles(path).ToList();
foreach (var file in files)
{
Image image = new Bitmap(file);
//Do some operations
}
我删除了主逻辑,因为这段代码仍然存在这个问题。当我添加GC.Collect()时
在foreach循环中,问题消失了,我没有得到异常
我的问题是:如果不调用Collect
方法,垃圾收集器清理不再需要的图像的速度是否太慢,或者我是否遗漏了其他内容
以前从未注意到这个问题。我从未想过会有问题,因为
//执行一些操作
部分对每个图像都需要~1秒的时间。对于垃圾收集器来说应该有足够的时间了。也许你应该使用使用:
var files = Directory.GetFiles(path).ToList();
foreach (var file in files)
{
using (Image image = new Bitmap(file))
{
// do work
}
}
这样,位图
将在迭代后处理您是否尝试显式处理该实例
var files = Directory.GetFiles(path).ToList();
foreach (var file in files)
{
Image image = new Bitmap(file);
//Do some operations
image.Dispose();
//image = null;
}
使用块可以更好地实现这一点。问题不在于GC,而在于位图的使用。虽然GC最终会将它们提取出来,但您需要使用
块将图像创建包装在中,以确保它们得到及时处理:
foreach (var file in files)
{
using (Image image = new Bitmap(file)) {
//Do some operations
}
}
@YvetteColomb:据我所知,这是一个重复的操作—在使用位图时,OP遇到了内存不足的问题—这是因为GC不会自动处理非托管内存。给出的解决方案回答了这个问题。另请参见下面罗马诺的回答。@PaulF好的,我错过了其他一些东西……我应该考虑使用位图
。谢谢大家!@YvetteColomb:OP说自动清理的速度很慢,并且会出现内存不足的问题——除非手动调用Collect。OP并没有说催收电话是问题所在&他已经接受了给出的答案。@YvetteColomb这确实是重复的。没有考虑过处理位图,认为GC是问题所在。@YvetteColomb:强大的Bababoom带来的最初问题是“我的问题是:垃圾收集器速度太慢,无法在不调用Collect方法的情况下清理不再需要的图像,还是我遗漏了其他东西?”-在这种情况下,答案是“是的-您忽略了需要处理位图的事实-否则GC在收集图像时会非常慢”-答案的两部分在重复问题中都提到了。中途没有变化。