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

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

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

最佳答案

来自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 block 来确保在出现异常时调用 DisposeDeleteObject 调用应该在 finally block 内以获得相同的效果。

关于c# - 这段代码中的什么导致了 C# 中的内存泄漏?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/29800477/

相关文章:

c# - 在一种 C# 方法中对日期或字符串类型进行排序

c# - 如何计算.NET 应用程序中的并发线程数?

c++ - 当结构对象超出范围时,如何删除结构对象内的指针?

android - PopupMenu PopupWindow$PopupViewContainer 泄漏

java - static HashMap 导致内存泄漏,但是如何纠正它?

c# - JSON反序列化将负值转换为绝对值

c# - 在 C# 中将 Excel 单元格值设置为小数。 .NET 2 和 .NET 4 之间的差异

c# - 我应该使用哪种优化算法来最大化时间限制的利润?

java - JVMTI:FollowReferences:如何跳过软/弱/幻像引用?

python - slurm python多处理超出内存限制