此代码中的内容导致C#中的内存泄漏?

时间:2015-04-22 14:19:04

标签: c# memory-leaks

在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();
}

有人可以建议请问这段代码中内存泄漏的原因是什么?

1 个答案:

答案 0 :(得分:9)

来自docs of GetHbitmap

  

您负责调用GDI DeleteObject方法来释放GDI位图对象使用的内存。有关GDI位图的更多信息,请参阅Windows GDI文档中的位图。

然后,从docs of FromHbitmap

  

FromHbitmap方法制作GDI位图的副本;因此,您可以在创建新图像后立即使用GDI DeleteObject方法释放传入的GDI位图。

看起来很清楚......你需要拨打DeleteObject

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

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