繁体   English   中英

如何释放在C ++中分配的C#中的内存

[英]How to free memory in C# that is allocated in C++

我有一个C ++ dll,它正在从相机读取视频帧。 这些帧在通过指向调用方(C#程序)的指针返回的DLL中分配。

当C#处理完特定的视频帧后,需要对其进行清理。 DLL接口和内存管理包装在C#中的一次性类中,因此它更易于控制。 但是,似乎内存没有被释放/释放。 我的进程的内存占用量不断增长,并且在一分钟之内,由于没有剩余的内存,我在C ++ DLL中遇到分配错误。

每个视频帧超过9 MB。 有很多代码,所以我只提供分配/取消分配/类型/等。

首先:在C ++中为摄像机字节分配原始缓冲区。

dst = new unsigned char[mFrameLengthInBytes];

第二:以无符号字符*的形式从原始指针传回DLL边界,并转换为C#中的IntPtr

IntPtr pFrame = VideoSource_GetFrame(mCamera, ImageFormat.BAYER);
return new VideoFrame(pFrame, .... );

因此,现在将IntPtr传递到VideoFrame类的CTOR中。 在CTOR内部,将IntPtr复制到该类的内部成员,如下所示:

IntPtr dataPtr;
public VideoFrame(IntPtr pDataToCopy, ...)
{
    ...
    this.dataPtr = pDataToCopy;
}

我的理解是那是一个浅表副本,并且该类现在引用了原始数据缓冲区。 框架已使用/已处理等。 稍后,处置VideoFrame类,并使用以下内容清理内存。

Marshal.FreeHGlobal(this.dataPtr);

我怀疑问题是... dataPtr是IntPtr,C#无法知道底层缓冲区实际上是9 MB,对吗? 有没有办法告诉它此时释放多少内存? 我使用了错误的C#免费方法吗? 有专门针对这种情况的一种吗?

您需要在使用的库中调用相应的“免费”方法。

通过new分配的内存是C ++运行时的一部分,调用FreeHGlobal将不起作用。 您需要对内存调用(一种或另一种) delete[]

如果这是您自己的库,则创建一个删除内存的函数(例如VideoSource_FreeFrame )。 例如:

void VideoSource_FreeFrame(unsigned char *buffer)
{
  delete[] buffer;
}

然后从C#中调用它,传入您返回的IntPtr

您需要(在c ++中) delete dst; 这意味着您需要提供C#代码可以调用的API,例如FreeFrame(...) ,它可以做到这一点。

我同意第一个答案。 不要使用任何神奇的礼仪咒语以C#代码释放它。 用C ++编写一个释放内存的方法,然后从您的C#代码中调用它。 不要养成在一个堆(本机)中分配内存并释放另一个堆(托管)的习惯,这只是个坏消息。

请记住本书《有效的C ++》中的规则之一:在构造函数中分配内存,并在析构函数中分配内存。 而且,如果您不能在析构函数中执行此操作,请使用类中的方法执行此操作,而不要使用某些全局(甚至更糟)的好友函数。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM