【问题标题】:Safe use of Marshal.Copy from raw bitmap data to managed array安全使用 Marshal.Copy 从原始位图数据到托管数组
【发布时间】:2010-01-05 09:31:17
【问题描述】:

不久前我发布了一个关于我的程序本质上是如何泄漏内存的问题:请参阅here。我现在已经专门跟踪了一些代码,其中我将 Bitmap 对象的原始字节复制到托管数组中。相关代码:

public class FastBitmap
{
    ...
    private byte[] rgbValues;
    private int height;
    private int width;
    private Bitmap image;

    public FastBitmap(Bitmap plainBitmap)
    {
        width = plainBitmap.Width;
        height = plainBitmap.Height;
        image = new Bitmap(plainBitmap);
        LockPixels(new Rectangle(0, 0, image.Width, image.Height));
    }

    private void LockPixels(Rectangle area)
    {
        if (locked)
            return;
        locked = true;
        BitmapData bitmapData = image.LockBits(area, ImageLockMode.ReadWrite,
                                PixelFormat.Format24bppRgb);
        IntPtr ptr = bitmapData.Scan0;
        int stride = bitmapData.Stride;
        int numBytes = image.Width * image.Height * 3;
        rgbValues = new byte[numBytes];
        for (int r = 0; r < image.Height; ++r)
        Marshal.Copy(new IntPtr((int)ptr + stride * r), 
                             rgbValues, image.Width * 3 * r, image.Width * 3);
    }
}

这就是导致内存无法恢复的所有代码范围,我想它与 Marshal.Copy() 有关,尽管我假设因为我是从位图复制的(清理自己?)到托管数组,没有问题。

所以问题是:是否有必要通过 IDisposable 接口或类似的方式清理 Bitmap 对象。在这种情况下使用 Marshal.Copy() 有什么(如果有的话)本质上是错误的,我在哪里可以解决这个问题?

谢谢

您知道我已经测试了以下代码,以验证确实是这导致了问题:

Bitmap bmp = new Bitmap(1000, 1000);
for (int n = 0; n < 100; ++n)
{
   FastBitmap fb = new FastBitmap(bmp);
}

在此序列的开始和结束时,总体内存使用量增加了大约 320mb 并且不会消失,无论您等待多长时间。

【问题讨论】:

    标签: c# bitmap marshalling


    【解决方案1】:

    你忘记调用 image.UnlockBits(bitmapData);

    【讨论】:

    • 非常感谢,几个小时的挫折,就这么简单。
    • 看来你错过了第二个代码sn-p,UnlockBitmap函数(调用UnlockBits),来自这篇文章:devx.com/webdev/Article/44658/1763/page/2
    猜你喜欢
    • 1970-01-01
    • 2013-02-09
    • 1970-01-01
    • 2012-07-06
    • 1970-01-01
    • 2011-03-13
    • 2023-03-03
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多