传递给C的SWIG生成对象的内存管理
Memory management of SWIG generated objects passed to C
我正在尝试使用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] = %dn", 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操作系统
谢谢你的帮助。
好的,感谢@Flexo,我找到了答案。
问题在于示例的实例化。在每个循环中创建PythonConnector()。只在循环外实例化一次似乎可以解决内存问题:
import time
import example
sizeBytes = 10000
buff = example.buffer(sizeBytes)
conn = example.PythonConnector()
for j in range(1000):
# Initialize data buffer
for i in range(sizeBytes):
buff[i] = i%256
buff[0] = 0
conn.print_array(buff.cast())
print(j)
del buff
time.sleep(10)
为什么许多连接器没有在原始代码中得到垃圾收集,这仍然是一个问题。
相关文章:
- 迭代时从向量和内存中删除对象
- 有没有一种方法可以使用placement new将堆叠对象分配给分配的内存
- Constexpr替代了新的放置方式,可以让内存中的对象保持未初始化状态
- 对具有动态分配的内存和析构函数的类对象的引用
- 当指向对象的指针作为参数传递给 std::thread 时,内存可见性
- 内存清理程序报告全局对象构造中未初始化值的使用
- 如何删除列出的"QGraphicsPathItem"对象以控制进程内存使用情况?
- 准确了解对象在内存中的映射方式
- 完全释放静态对象内存
- C++ 对象内存管理
- 循环中的自动变量和自动对象内存分配
- 每个对象内存分配有多少开销
- 是隐式创建的默认构造函数,负责分配对象内存
- 使用 make_unique 语句重新分配unique_ptr对象 - 内存泄漏
- C++对象内存布局
- C++对象内存消耗
- 谷歌模拟全局模拟对象内存泄漏
- 静态工厂方法和静态对象内存泄漏
- 关于对象内存布局的假设
- 如果我在管理C++对象内存的目标 C 中混合C++代码,ARC 会处理它