c# - 垫子没有被正确销毁
问题描述
在我用 C# 编写的软件中,我实现了一个用于内部目的的图像类。在那个班级里,我拿着一份Mat
来自 emgu 的简历。
class MyOwnImage : IDisposable
{
private Mat mat;
public MyOwnImage( Mat mat ) {
this.mat = mat;
}
public void Dispose() {
mat.Dispose();
}
//...
}
Dispose()
现在,我发现,无论我是否调用Image
对象,我的内存使用量都在增长。我仔细看了看这Mat
门课,发现它里面有一个IntPtr
. 所以,我试了一下,如果手动释放指针会有所不同:
class MyOwnImage : IDisposable
{
private Mat mat;
public MyOwnImage( Mat mat ) {
this.mat = mat;
}
public void Dispose() {
Marshal.FreeHGlobal( mat.DataPointer ); // data pointer is the IntPtr
mat.Dispose();
}
//...
}
我有点惊讶,但它解决了内存溢出的问题。所以,我假设我必须Mat
手动销毁对象内部的数据。Dispose()
之后,如果有人忘记手动生成图像,我尝试通过添加析构函数来使其更加稳定。
class MyOwnImage : IDisposable
{
private Mat mat;
public MyOwnImage( Mat mat ) {
this.mat = mat;
}
~MyOwnImage() {
destroy();
}
private void destroy() {
Marshal.FreeHGlobal( mat.DataPointer ); // data pointer is the IntPtr
mat.Dispose();
}
public void Dispose() {
destroy();
}
//...
}
可悲的是,这变成了一个新问题:有时,当调用析构函数时,Mat
对象似乎已经被销毁了。随后,AccessViolationExcetion
在调用FreeHGlobal(...)
. 现在,我进行了另一个测试并删除destroy()
了函数内部的Dispose()
调用。
class MyOwnImage : IDisposable
{
private Mat mat;
public MyOwnImage( Mat mat ) {
this.mat = mat;
}
~MyOwnImage() {
destroy();
}
private void destroy() {
Marshal.FreeHGlobal( mat.DataPointer ); // data pointer is the IntPtr
mat.Dispose();
}
public void Dispose() {
//destroy();
}
//...
}
奇怪的是,这并没有改变任何事实,当调用析构函数时,mat
内部MyOwnImage
似乎已经消失了~MyOwnImage
。
最后,我想知道几件事:
- 如果我手动调用
Dispose()
,是否有可能稍后也会调用析构函数? - 有没有可能在
MyOwnImage
这个类的析构函数被调用之前,内部对象就被销毁了? - 如果有 OpenCV 专家:是否有可能处理垫子不会释放里面的数据?如果是,是错误还是有原因?
解决方案
J...在评论中指出了这个问题。
违反了所有权模式。正如他所建议的,我Mat
在 MyOwnImage 中克隆了该对象,现在它正在工作。
class MyOwnImage : IDisposable
{
private Mat mat;
public MyOwnImage( Mat passedMat ) {
var copy = new Mat();
passedMat.CopyTo( copy );
mat = copy;
}
public void Dispose() {
mat.Dispose();
}
//...
}
推荐阅读
- react-native - 运行“react-native run-android”时出错
- javascript - 为流媒体服务器正确拆分 MPEG-1 第 3 层
- core-location - IOS 13:CoreLocation:CLVisit 在一段时间后停止调用委托
- css - 检查复选框是否被选中
- ios - UIStoryboard 控制器类作为基类
- python-3.x - 制作二维图 ['NoneType' 对象不可迭代]
- loops - 如何使用 xpath 连接不同的子节点
- slice - xarray中的角度切片
- node.js - fetch-api 中的“最大重定向”错误是什么意思?
- csv - 递归对象写入平面 csv 文件