C# 我是否在循环中泄漏内存?

C# 我是否在循环中泄漏内存?,c#,loops,memory-leaks,C#,Loops,Memory Leaks,我是一个新的程序员,我刚刚提出了一个内存泄漏的问题。如果我在一个循环中声明一个变量,让它一次又一次地被声明,我是否在泄漏内存? 例如,我有 while(true) { Image<Gray, Byte> MyImage = new Image<Gray, Byte> (1024, 768); //do something else } while(true) { Image MyImage=新图像(1024768); //做点别的 } 我知道这是一个无

我是一个新的程序员,我刚刚提出了一个内存泄漏的问题。如果我在一个循环中声明一个变量,让它一次又一次地被声明,我是否在泄漏内存? 例如,我有

while(true)
{
    Image<Gray, Byte> MyImage = new Image<Gray, Byte> (1024, 768);
    //do something else
}
while(true)
{
Image MyImage=新图像(1024768);
//做点别的
}

我知道这是一个无限循环,但我的问题是关于记忆。在这个循环中,内存使用量增长快吗?我应该手动释放MyImage吗?

您需要在使用MyImage.Dispose()后调用它

另一种方法是将代码更改为:

while(true)
{
    using(Image<Gray, Byte> MyImage = new Image<Gray, Byte> (1024, 768)){
        //do something else
    }
}
while(true)
{
使用(Image MyImage=newimage(1024768)){
//做点别的
}
}
如果我在一个循环中声明一个变量,让它一次又一次地被声明,我是否在泄漏内存

不,您没有,其他人提到的问题可能是,如果图像正在包装图像对象


但对于您的问题,在循环中声明一个变量并在每次迭代中为其分配一个新值并不是问题。在某些情况下,紧循环可能会导致OOM问题。但是,
Image
实现了
IDisposable
,因此请务必使用
语句调用它,以便在使用完资源后释放资源

using (Image<Gray, Byte> MyImage = new Image<Gray, Byte>(1024, 768))
{
  //do stuff
}
使用(Image MyImage=newimage(1024768))
{
//做事
}

确保
Image
实现
IDisposable
如果
Image
实现任何托管对象。

在您的问题的一般形式中,您本身并没有泄漏内存,但您增加内存占用的速度可能快于GC减少内存占用的速度(取决于您正在使用的对象的确切行为和内存占用)。如果是这样,这将产生大量类似内存泄漏的效果

在您的特定示例中,映像对象包含非托管资源,其中可能包括内存(或文件句柄或GDI对象等)。正如其他答案所述,如果您不进行处置,这些非托管资源将不会被回收(或者在GC的第二次过程中被回收,如果它们具有终结器)。

垃圾收集器(GC)最终将为您完成这项工作。在您建议的情况下,您必须小心,因为在这种情况下,GC将尝试管理它花费在垃圾收集和应用程序内存消耗(工作集)上的时间。因此,应用程序可能会消耗比所需更多的内存,特别是在您所说明的情况下

CLR完全自动处理此内存,您自己也无法释放托管内存。例如,请考虑下面的

public void Test()
{
    byte[] myArray = new Byte[1000];
    // ...
}
当执行
Test
时,在内存堆上分配一个容纳1000字节的数组。该数组由存储在局部变量堆栈上的变量
myArray
引用。当此方法退出时,该局部变量弹出范围,这意味着内存堆上的数组没有任何引用。孤立数组then有资格被GC回收。但是,此收集可能不会立即发生,因为CLRs决定是否收集取决于许多因素(可用内存、当前内存分配、自上次收集以来的时间等)t这意味着在垃圾收集之前所花费的时间有一个不确定的延迟

鉴于上述情况,在您描述的案例中,在循环/包含方法的持续时间内,内存消耗将大幅增加。在这里,最好使用
using
语句

while (true)
{
    using (Image<Gray, Byte> MyImage = new Image<Gray, Byte> (1024, 768))
    {
        // ...
    }
}
Asside:通过查询性能计数器(使用System.Diagnostics),您始终可以自己检查此类内存消耗(测试进程的实际内存消耗):


注意:读取性能计数器需要管理员权限。

我会冒险猜测,然后说是……但我不是100%确定,所以请不要把它当作福音。@Killercam你确定吗?因为我听到一些不同的声音,我不知道。你的意思是,在这种情况下,图像对象可以,还是一般来说?我意识到可能是class不实现
IDisposable
。因此,如果a-它实现IDisposable或b-它使用实现IDisposable的东西,那么您应该实现它来处理内部对象。这只是为了提高效率还是真正的内存泄漏?IDisposable类通常使用无法释放的内存调用til Dispose()方法。由于您可能在无限循环中使用它们,这可能会导致内存泄漏(我的意思是,如果您使用一次性对象而不调用Dispose,则会导致内存泄漏)Emgu.CV.Image如果您了解OpenCV,Image是IplImage的C#托管包装,它确实有一个Dispose methodPerfect。请调用
Dispose()
或使用
using
语句:)
while (true)
{
    Image<Gray, Byte> MyImage = new Image<Gray, Byte> (1024, 768);
    // ...
    MyImage.Dispose();
}
string procName = Process.GetCurrentProcess().ProcessName;
using (PerformanceCounter pc = new PerformanceCounter("Process", "Private Bytes", procName))
    Console.WriteLine(pc.NextValue());