这段代码中的什么导致了 C# 中的内存泄漏?

What in this code causes memory leak in C#?

在 Windows 任务管理器中,我发现我的程序的内存使用量随着时间的推移而增加,而它是 运行。内存泄漏是由下面的代码引起的。该代码是一个循环遍历图像列表并根据 MSDN 中的代码示例调整它们的大小。所有资源似乎都受到管理并通过 .Dispose() 释放。

foreach ( string file in files )
{
    image = Image.FromFile( file );

    Rectangle cropRect = new Rectangle( 0, 0, 1000, 1000 );
    Bitmap src = ( Bitmap ) image;
    Bitmap target = new Bitmap( cropRect.Width, cropRect.Height );

    using ( Graphics g = Graphics.FromImage( target ) )  
    {
        g.DrawImage( src, new Rectangle( 0, 0, target.Width, target.Height ),
                                        cropRect,
                                        GraphicsUnit.Pixel );
    }

    image.Dispose();
    image = Image.FromHbitmap( target.GetHbitmap() );
    src.Dispose();
    target.Dispose();
    image.Dispose();
}

有人能告诉我这段代码中内存泄漏的原因是什么吗?

来自docs of GetHbitmap

You are responsible for calling the GDI DeleteObject method to free the memory used by the GDI bitmap object. For more information about GDI bitmaps, see Bitmaps in the Windows GDI documentation.

然后,从 docs of FromHbitmap:

The FromHbitmap method makes a copy of the GDI bitmap; so you can release the incoming GDI bitmap using the GDI DeleteObject method immediately after creating the new Image.

看起来很清楚...你需要调用 DeleteObject:

[DllImport("gdi32.dll")]
private static extern bool DeleteObject(IntPtr hObject);

正如 SJoshi 指出的那样,您应该使用 using 块来确保在出现异常时调用 DisposeDeleteObject 调用应该在 finally 块内以获得相同的效果。