【问题标题】:Memory Leak when Marshal.CopyMarshal.Copy 时内存泄漏
【发布时间】:2014-10-06 02:44:11
【问题描述】:

我注意到我的程序正在泄漏内存。于是我用 dotMemory 查找泄漏,看起来这是导致泄漏的函数:

    private void LoadBits()
    {
        // Lock the bitmap's bits.  
        Rectangle rect = new Rectangle(0, 0, bm.Width, bm.Height);
        bmpData = bm.LockBits(rect, System.Drawing.Imaging.ImageLockMode.ReadWrite, bm.PixelFormat);
        stride = bmpData.Stride;

        // Get the address of the first line.
        IntPtr ptr = bmpData.Scan0;

        // Declare an array to hold the bytes of the bitmap. 
        byteCount = Math.Abs(bmpData.Stride) * bm.Height;
        bytes = new byte[byteCount];

        // Copy the RGB values into the array.
        System.Runtime.InteropServices.Marshal.Copy(ptr, bytes, 0, byteCount);
    }

这就是我解锁这些位的方式。

    private void SaveBits()
    {
        // Update Stuff
        IntPtr ptr = bmpData.Scan0;

        System.Runtime.InteropServices.Marshal.Copy(bytes, 0, ptr, byteCount);
        bm.UnlockBits(bmpData);
    }

我为这个类实现了 IDisposable 接口。我在那里调用 SaveBits,所以即使我忘记调用 SaveBits,GC 也应该为我做这件事。 是的,我确实调用了 bm.Dispose() 并在 Dispose 方法中将所有内容设置为 null。

【问题讨论】:

  • LoadBits 和 SaveBits 使用不同的变量。一个是_bm,另一个是bm,你能在错误的对象上解锁位吗?也可以在调用SaveBits() 之前多次调用LoadBits(),这也会导致内存泄漏。尝试将bmpData = null 放在SaveBits() 的末尾,并将if (bmpData != null) throw new InvalidOperationException(); 放在LoadBits() 的开头,看看是否会抛出异常。
  • 我在发布问题后进行了重构。所以“LoadBits”显示的是旧的 var 名称。请允许我更新它。
  • 如果做空检查,抛出异常,不抛出吗?
  • 我无法加载两次。 Bitmap 类抛出异常,表示内存已被锁定。根据您的建议修改代码并执行 null 检查会导致抛出异常。
  • 好吧,如果它导致你发现你的问题,在调用 SaveBits 清除它之前,有东西正在写入 bmpData。您正在失去锁定位的句柄,这就是您的内存韭菜的原因。

标签: c# memory memory-leaks


【解决方案1】:

完成后您需要UnlockBits()

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2022-01-06
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-09-19
    • 2011-10-08
    • 2013-01-20
    • 2011-10-31
    相关资源
    最近更新 更多