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】:
可以使用malloc
和free
(new
和delete[]
也可以),只是如果因为错误,异常需要提前返回,请不要忘记先调用daellocation函数, mexErrMsgTxt
等。查看代码中的每个 return
、try
/catch
和 mexErrMsg*
块。
如果您确定您的代码中没有错误,请尝试clear mex
看看您是否恢复了记忆。
另外,我建议以允许您附加调试器的方式构建您的 MEX 文件。例如,如果您在 Windows 上,您可以关注these instructions,让您直接在 Visual Studio 中构建,这样可以轻松调试(只需附加到正在运行的 MATLAB.exe)。
更新:解决您对top
报告的内存的评论。您的 mex 文件使用的 C 运行时库与 MathWorks 用于实现 mxMalloc
和 mxFree
的内存管理的任何 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 没有任何方法可以阻止它。你在看什么内存指标? ps
或 top
的哪一列说明了这个问题?
我正在查看 top
中的 RES 列。
@VilenJumutc 释放内存只会将内存释放到运行时库。由库将其返回到操作系统,它可以在top
的RES 中观察到。查看我的更新。
感谢@chappjc 的回答。在连续执行 MEX 调用一百次后,我发现了free(...)
的这种后果,并观察到系统因空闲内存不足而开始出现故障。以上是关于Matlab 是不是在 MEX/C 代码中阻止或拦截 free()的主要内容,如果未能解决你的问题,请参考以下文章
MATLAB 是不是使用 OpenCv CascadeClassifier?