c#如何处理内存

时间:2010-01-15 19:01:16

标签: c# pass-by-reference

我有一个班级“skImage”。这个类有一个私有变量(带有暴露它的公共属性)

private Image _capturedImage;  

这个类的构造函数如下:

   public skImage(Image captured) {

            _capturedImage = captured;

        }

它还有以下方法:

public bool Invert() {

        Bitmap b = new Bitmap(_capturedImage);

        unsafe {
         //random code not relevant.
        }

        _capturedImage = b;
        b.Dispose();
        return true;
    }

然后它有一个save()方法,它只调用:

  _capturedImage.Save(_saveFullLocation);

现在如果我运行invert方法然后尝试调用save它会引发异常(参数无效)。在谷歌搜索此异常后,我似乎处理了图像。我可以看到我在反转方法之后处理“b”。

我的问题是,当我做_capturedImage = b这意味着两个变量现在都拥有一个对象的引用?我不想那样。我希望b被销毁以减轻记忆,以便GC可以收集它。如何将b转移到_capturedImage并销毁b。

感谢

5 个答案:

答案 0 :(得分:3)

  

这是否意味着两个变量现在都拥有对象的一个​​引用?

是。但是,引用只是一个参考 - 它不会花费太多内存。

  

我希望b被销毁

你不能销毁一个引用 - 你只能自己处理它。

你应该写下:

而不是处理b
_capturedImage.Dispose();
_capturedImage = b;

答案 1 :(得分:2)

_capturedImage和b是对同一底层对象的引用。调用b.Dispose();还将处理_capturedImage,因为它们都是指向同一blob数据的引用。一旦b超出范围(即Invert返回时),b将停止存在但GC不会收集数据,因为_capturedImage仍然指向它。

答案 2 :(得分:1)

当你必须创建一个新的Bitmap来替换另一个Bitmap时,一般的经验法则是保存对旧Bitmap的引用,将新的Bitmap分配给用来存储它的变量,然后处理旧的Bitmap。

这样,如果您有任何与修改存储变量相关的行为,则可以避免“闪烁”。这通常用于双缓冲;

public bool Invert() 
{
    //this will create a clone of _captureImage, so you effectivly have 2 Bitmaps at that point
    Bitmap b = new Bitmap(_capturedImage); 

    unsafe 
    {
     //random code not relevant.
    }

    var old = _capturedImage; //store old reference

    //assign, any events will seemlesly transition from the old to the new Bitmap
    _capturedImage = b; 
    old.Dispose(); //get rid of the old Bitmap

    return true;
}

答案 3 :(得分:0)

正如其他人所提到的那样,你正在使b和_capturedImage指向同一个对象,所以当你处理b时,_capturedImage也会被抛弃。

我认为没有必要在这里调用Dipose()。变量在函数范围内声明,因此它没有引用,GC会自动清理它。

事实上,我甚至没有看到'b'变量的需要。为什么不在整个函数中使用'_capturedImage'并保持简单?

答案 4 :(得分:-2)

image.Clone()

您必须再次将结果转换为数据类型,因为Clone()返回System.Object。

编辑:我一定是误解了这个问题。我以为你想要的图像无法通过其他地方的代码处理。只要您在内存中共享对同一图像的引用,所有知道该图像的人都可以处理它,从而有效地阻止您。通过克隆图像,您可以确保没有其他人(或您编写的其他代码)可以处理它。