加入收藏 | 设为首页 | 会员中心 | 我要投稿 李大同 (https://www.lidatong.com.cn/)- 科技、建站、经验、云计算、5G、大数据,站长网!
当前位置: 首页 > 百科 > 正文

c# – 从原始位图数据到托管数组安全使用Marshal.Copy

发布时间:2020-12-15 08:24:41 所属栏目:百科 来源:网络整理
导读:我不久前发布了一个问题,关于我的程序本质上是如何泄漏内存:请参阅 here.我现在已经专门跟踪了一些代码,其中我将Bitmap对象的原始字节复制到托管数组中.相关代码: public class FastBitmap{ ... private byte[] rgbValues; private int height; private in
我不久前发布了一个问题,关于我的程序本质上是如何泄漏内存:请参阅 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,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()有关,虽然我曾经假设我从Bitmap复制(自己清理) ?)到托管阵列,没有问题.

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

谢谢

只是你知道我已经测试了下面的代码,以验证它确实导致了这个问题:

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

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

解决方法

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

(编辑:李大同)

【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容!

    推荐文章
      热点阅读