Matlab 是不是在 MEX/C 代码中阻止或拦截 free()

Posted

技术标签:

【中文标题】Matlab 是不是在 MEX/C 代码中阻止或拦截 free()【英文标题】:Does Matlab blocks or intercepts free() in MEX/C-codeMatlab 是否在 MEX/C 代码中阻止或拦截 free() 【发布时间】:2015-02-05 16:39:28 【问题描述】:

我在为 Matlab 编译的 MEX/C 代码中有一个奇怪的情况。我使用malloc(...) 进行动态内存分配,并调用free(...) 来释放此内存。退出 MEX 例程后,我可以看到分配的内存根本没有释放。另一方面,如果我使用 mxMalloc(...)mxFree(...) 一切都很好。如果我照顾free(...),我假设malloc(...) 的使用不是禁止的。在 Matlab 规范中,我找不到任何关于拦截或阻止基本 C 库的信息。虽然有一些关于它的奇怪帖子,比如Matlab Central。

【问题讨论】:

“退出 MEX 例程后,我可以看到分配的内存根本没有释放”——是什么让你这么认为? 我可以通过查看 Matlab 进程在我的系统监视器 (Linux) 中看到它。在我的MEX 代码中,我创建了 BIG 矩阵,每次我看到为这些矩阵分配的 100+ MB 都被 Matlab 进程保留。 我认为你必须展示一些代码。重现问题的最小示例。 您可以在此处找到代码:mathworks.com/matlabcentral/fileexchange/… 并解决内存问题,我已将 free(...)malloc(...) 替换为 mxFree(..)mxMalloc() 【参考方案1】:

可以使用mallocfreenewdelete[]也可以),只是如果因为错误,异常需要提前返回,请不要忘记先调用daellocation函数, mexErrMsgTxt 等。查看代码中的每个 returntry/catchmexErrMsg* 块。

如果您确定您的代码中没有错误,请尝试clear mex 看看您是否恢复了记忆。

另外,我建议以允许您附加调试器的方式构建您的 MEX 文件。例如,如果您在 Windows 上,您可以关注these instructions,让您直接在 Visual Studio 中构建,这样可以轻松调试(只需附加到正在运行的 MATLAB.exe)。


更新:解决您对top 报告的内存的评论。您的 mex 文件使用的 C 运行时库与 MathWorks 用于实现 mxMallocmxFree 的内存管理的任何 C 运行时库不同。请注意,free 将内存返回给运行时库,而不是返回给操作系统。因此,内存可能会在不同时间使用不同的运行时库返回给操作系统。来自Modern Memory Managment at ONLamp.com:

malloc通常不会将释放的内存返回给操作系统;它一直归进程所有,直到它终止。该进程可以在下次请求更多内存时重用它,但其他程序将无法访问它,即使没有其他内存可用。由此推论,程序的内存占用量就是在任何时候进行的最大分配的大小。

众所周知,减少分配给进程的内存块的大小非常困难。见this answer。答案重申了这一点:“要将内存返回给操作系统,首先必须将从这些大块之一分配的所有内存释放给运行时库。然后运行时库可以,如果它愿意,告诉操作系统释放那块内存。”也可以在那里查看其他答案。

因此,top 报告的驻留集大小 (RSS/RES) 在free 执行时不会立即下降也就不足为奇了。 MATLAB 内部使用的malloc 与 mex 文件中使用的明显不同,甚至可能是自定义实现而不是标准运行时版本。

如果是实际泄漏,您将无法取回此内存。如果您推送系统,该内存应该返回到空闲池。但是,我必须将此视为mxMalloc 相对于malloc 的优势,并声明我自己实际上并未复制此效果。

【讨论】:

感谢您的回答。代码在没有错误的情况下退出,我引入了额外的try/catch 块来防止在没有释放内存的情况下退出。没有任何帮助,即使clear mex 也不能解决这个问题。在这种情况下,free(...) 似乎根本不起作用……或者被 Matlab 阻止了。 @VilenJumutc Mex 文件是一个共享库,它使用独立于 MATLAB 的 C 运行时库。我认为 MATLAB 没有任何方法可以阻止它。你在看什么内存指标? pstop 的哪一列说明了这个问题? 我正在查看 top 中的 RES 列。 @VilenJumutc 释放内存只会将内存释放到运行时库。由库将其返回到操作系统,它可以在top 的RES 中观察到。查看我的更新。 感谢@chappjc 的回答。在连续执行 MEX 调用一百次后,我发现了free(...) 的这种后果,并观察到系统因空闲内存不足而开始出现故障。

以上是关于Matlab 是不是在 MEX/C 代码中阻止或拦截 free()的主要内容,如果未能解决你的问题,请参考以下文章

Cholesky 分解的 Matlab Mex C 实现

我的 Matlab 代码是不是适合将 PCA 应用于数据?

MATLAB 是不是使用 OpenCv CascadeClassifier?

阻止 ArrayList 在 Excel、Apache POI 中收集多个数据而不是一个数据

Matlab:实现 CTRL+C 的功能,但在代码中

由于被CORS策略(javascript,html和css)阻止,程序在Firefox中运行但不是chrome