r - 在 R 中执行嵌套 C 代码时发生内存泄漏
问题描述
我目前正在开发一个 R 包,其中时间性能至关重要,这就是我在 C 中实现关键部分的原因。(我习惯于 C。至少现在我不打算使用 C++。)
在我看来,SEXP 结构在让 C 函数内部通信时也非常方便。因此,在我的 C 代码中,所有函数都将 SEXP 作为参数并返回 SEXP。当然,我为每个单独的功能处理了平衡的 PROTECT 和 UNPROTECT。
到目前为止,我的主循环位于 R 中,它一遍又一遍地调用 C 函数。由于这个循环还计算了一些其他的东西,我想把这个循环也转移到 C 中,并编写了一个与 R 循环等效的 C 函数。将这部分转移到 C 现在会导致我以前从未见过的重大内存泄漏:在每次迭代中,使用的内存不断增加,直到分配失败。C 中的循环也可以正确处理 PROTECT。还值得一提的是,在取消执行后调用 gc() 并不能清理数 GB 的 UNPROTECTED SEXP 的混乱。
那么为什么会发生这种内存泄漏呢?R只能在返回R时正确清理吗?在内部处理 SEXP 时是否有 PROTECT/UNPROTECT 的替代方案,例如某种免费的?(我还尝试重写内存密集型部分以使用 R_PreserveObject 和 R_ReleaseObject。)我使用 valgrind 的迭代次数较少,以便程序可以在达到分配限制之前完成。那里没有可见的内存泄漏。
为了说明这个问题,R 中这个相当愚蠢的代码块没有任何泄漏:
while(TRUE) {
eval <- .Call(my_function, argument1, argument2, 42)
}
现在调用执行此循环的外部 C 函数
.Call(C_loop, argument1, argument2)
和
SEXP C_loop(SEXP argument1, SEXP argument2) {
SEXP argument3 = PROTECT(ScalarInteger(42));
while(1) {
my_function(argument1, argument2, argument3);
}
UNPROTECT(1);
return R_NilValue;
}
产生泄漏。
解决方案
推荐阅读
- sql - SQL 查询无法正常工作(不确定)
- sql-server - 识别“字符空间字符”
- c# - 解析没有花括号的代码块的技术
- ios - 错误:无法加载文件列表的内容:'/Target Support Files/Pods-xx/Pods-xx-frameworks-Debug-input-files.xcfilelist'(在目标'xx'中)
- c++ - 合并两个 C++ 数组时如何修复“无效指针”
- sql-server - 如何从 SQL Server 2008 中的 DDMMYYYY 中选择 MMYYYY
- python - 如何使用子进程保存python文件的输出并将所有这些附加到一个文件中?
- python - 在数据框中选择时间窗口
- java - 我刚刚安装了eclipse,为什么eclipse不能运行我的任何代码?
- javascript - 如何使用正则表达式将字符串“folder/lower-case-with-dash”转换为“folderLowerCaseWithDash”(即camelCase格式)?