MATLAB中的内存泄漏> MEX文件>托管DLL

时间:2012-09-19 14:10:31

标签: matlab memory-leaks c++-cli mex

我的MEX file是用C ++ / CLI编写的,并调用用C#编写的DLL。

当gcnew'ing一个对象时,当mexFunction返回时,它不应该被垃圾收集吗? 它的引用应该丢失,但似乎没有任何垃圾收集...每次调用mex函数都会增加MATLAB的内存分配(不,内存不用于MATLAB变量)。

我已尝试使用窄范围创建一个大的虚拟值,当单步执行MEX文件时,我可以看到已分配和释放的内存。但是在mexFunction =(

)中创建的主要对象不是这样

我试图在析构函数和终结器中删除它,但我无法将其转换为垃圾收集。返回MATLAB时如何释放托管内存?

我不认为外部DLL文件管理器是问题。为了说明,我创建了这个愚蠢的mexFunction:

public ref class Foo
{
    public:
        Foo()
        {
            Dictionary<int,String^>^ bar = gcnew Dictionary<int,String^>;
            for(int i=0;i<10000000;i++)
            {
                bar->Add(i, "abcdefghijklmnopqrstuvxyz");
            }
        }
};

void mexFunction(int nlhs, mxArray* plhs[], int nrhs, mxArray* prhs[])
{
    Foo^ test = gcnew Foo();
}

这会使MATLAB的内存大约300 MB,尽管后续调用不会像我的真实MEX文件那样进一步增加内存。

编辑:

我回答了自己的问题,罪魁祸首是 mxArrayToString

2 个答案:

答案 0 :(得分:2)

垃圾收集将内存标记为.NET堆中可用的内存。它不会缩小.NET堆(这将使内存可用于其他进程以及可用于进程中非.NET代码的地址空间)。

明确记载大型对象堆永远不会缩小,而拥有1000万条目的词典可能足以进入LOH。

答案 1 :(得分:2)

我发现了问题,结果发现它毕竟不是.net相关...对不起那个红鲱鱼

由于我没有使用new,malloc或mxMalloc,我错误地认为所有非托管内存都在堆栈中并在mexFunction结束时清理。

但是mxArrayToString不会像mxGetData和其他mx *函数那样返回指向MATLAB数据的指针。它将数据复制到堆上,并且必须调用mxFree来释放它。我使用mxArrayToString作为输入来创建System :: String ^,唯一需要的更改是保存临时字符指针,将其用于String ^构造函数然后mxFree它。

再一次对SEO:来自 mxArrayToString 的指针需要 mxFree&#39; d