C#如何处理内存
我有一个类“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.
谢谢
I have a class "skImage". This class has a private variable (with a public property that exposes it)
private Image _capturedImage;
the constructor of this class looks like:
public skImage(Image captured) {
_capturedImage = captured;
}
It also has the following method:
public bool Invert() {
Bitmap b = new Bitmap(_capturedImage);
unsafe {
//random code not relevant.
}
_capturedImage = b;
b.Dispose();
return true;
}
and then it has a save() method, which just calls:
_capturedImage.Save(_saveFullLocation);
now if i run the invert method and then try calling save it throws an exception (parameter is not valid). After googling this exception it seems like I am disposing of the image. I can see that I am disposing "b" after the invert method.
My question is that when i do _capturedImage = b
does that mean both variables now hold one reference to the object? I dont want that. I want b to be destroyed to relieve memory so the GC can collect it. How do i transfer b to _capturedImage and destroy b.
thanks
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(5)
是的。然而,引用只是引用——它不会消耗太多内存。
您不能销毁引用 - 您只能处置对象本身。
您应该编写以下内容,而不是处理 b:
Yes. However, a reference is only a reference - it does not cost much memory.
You cannot destroy a reference - you can only dispose the object itself.
Instead of disposing b you should write:
_capturedImage 和 b 是对同一底层对象的引用。调用 b.Dispose();还将处理 _capturedImage,因为它们都是指向同一数据块的引用。一旦b超出范围(即当Invert返回时),b将停止存在,但GC不会收集数据,因为_capturedImage仍然指向它。
_capturedImage and b are references to the same underlying object. Calling b.Dispose(); will also dispose of _capturedImage, since they are both references which point to the same blob of data. Once b is out of scope (i.e. when Invert returns), b will stop existing but the GC will not collect the data since _capturedImage still points to it.
当您必须创建一个新位图来替换另一个位图时,一般经验法则是保存对旧位图的引用,将新位图分配给用于存储它的变量,然后处理旧位图。
这样,如果您有任何与存储变量的修改相关的行为,就可以避免“闪烁”。这通常用于双缓冲;
A general rule of thumb when you have to create a new Bitmap to replace another is to save the reference to the old Bitmap, assign the new one to the variable you use to store it, then dispose the old one.
This way, should you have any behavior related to the modification of the storing variable, you avoid "flickering". This is commonly used in double-buffering;
正如其他人提到的,您使 b 和 _capturedImage 指向同一个对象,因此当您处置 b 时, _capturedImage 也会被处置。
我认为没有必要在这里调用 Dipose() 。该变量是在函数范围内声明的,因此不会有任何引用,GC 会自动清理它。
事实上,我什至不认为需要“b”变量。为什么不在整个函数中使用“_capturedImage”并保持简单呢?
As others have mentioned, you're making b and _capturedImage point to the same object, so when you Dispose of b, _capturedImage is diposed too.
I don't see any need to call Dipose() here. The variable is declared in the scope of the function, so it will have no references and the GC will clean it up automatically.
In fact, I don't even see the need for the 'b' variable. Why don't you just use '_capturedImage' throughout the whole function and keep things simple?
image.Clone()
由于 Clone() 返回 System.Object,因此您必须再次将结果转换为您的数据类型。
编辑:我一定是误解了这个问题。我以为你想要一个无法通过其他地方的代码处理的图像。只要您共享对内存中同一图像的引用,其他知道该图像的人就可以处理它,从而有效地把您搞砸了。通过克隆图像,您可以确保其他人(或您编写的其他代码)无法处置它。
image.Clone()
You'll have to cast the result to your data type again though since Clone() returns a System.Object.
Edit: I must have misunderstood the problem. I thought you wanted to have an image that could not get disposed by code elsewhere. As long as you share references to the same image in memory, everyone else who is aware of that image can dispose it, effectively screwing you over. By cloning the image you ensure that nobody else (or some other code you wrote) can dispose it.