【发布时间】:2016-04-07 13:01:54
【问题描述】:
我正在尝试使用 SWIG 包装一个用 C++ 编写的 Python 库。该库使用接受字节缓冲区作为参数的函数调用。在 Python 中,我使用 SWIG 的 %array_class 创建这些字节缓冲区。我制作了一个概念验证程序来测试这一点,我注意到与将这些缓冲区传递给 C++ 相关的严重内存泄漏。具体来说,运行下面的代码稳定地提高 Python 应用程序的内存使用率(如在任务管理器中观察到的)高达约 250MB,程序停止。 C 的打印输出表明程序确实按预期运行,但只是占用了更多内存。 del buff 语句运行,但没有释放内存。我尝试在每个循环中创建和删除缓冲区,但结果相同。
在 C++ 中运行 delete x; 会使我的程序完全崩溃。
我的 Swig 接口文件:
%module example
%include "carrays.i"
%array_class(uint8_t, buffer);
%{
#include "PythonConnector.h"
%}
%include "PythonConnector.h"
C 头文件:
class PythonConnector {
public:
void print_array(uint8_t *x);
};
最小的 C 定义函数
void PythonConnector::print_array(uint8_t *x)
{
//int i;
//for (i = 0; i < 100; i++) {
// printf("[%d] = %d\n", i, x[i]);
//}
//delete x; // <-- This crashed the program
return;
}
测试者 Python 脚本
import time
import example
sizeBytes = 10000
buff = example.buffer(sizeBytes)
for j in range(1000):
# Initialize data buffer
for i in range(sizeBytes):
buff[i] = i%256
buff[0] = 0
example.PythonConnector().print_array(buff.cast())
print(j)
del buff
time.sleep(10)
我错过了什么吗?我怀疑 SWIG 每次将缓冲区传递给未进行垃圾收集的 C++ 时都会创建一些代理对象。
编辑:
- SWIG 版本 3.0.7
- CPython 版本 3.5 x64
- Windows 10 操作系统
感谢您的帮助。
【问题讨论】:
-
如果我不得不猜测的话,我认为泄漏来自对
example.PythonConnector()的重复调用。你已经很好地提出了这个问题 - 几乎所有需要尝试的东西都在那里。您也可以将类定义添加到您的示例中吗?我想这只是class PythonConnector { public: void print_array(unit8_t*); };,但在我(或其他人)进一步调查之前检查一下会很好。 (还有你使用的是哪个版本的 SWIG 和 Python?) -
@Flexo 我做了你建议的补充。我还将 python 连接器的实例化移到了循环之外(仅实例化一次),并且像一个魅力一样工作。内存始终保持在 6MB。谢谢。
-
希望我能写一个答案,解释为什么会在本周末晚些时候发生这种情况
标签: python c++ memory-management swig