Python 调用 C 插件后,需要手动释放内存吗?

2020-12-05 18:50:52 +08:00
 black11black
如题,最近在用 cython 做局部加速,已经发了几个帖子了。目前项目进展顺利,试做型代码量比 py 大三倍左右,运行速度快 200 倍,已经很满意了。

考虑到一个部署的问题是,我不太清楚 py 和 so 交互的原理,如果调用 so 函数,so 开辟的内存空间还受到 py 解释器控制吗?当完成调用,返回结果时,它是否会像一个 py 函数一样回收整个命名空间内的内存?(所以我不需要手动回收容器的内存)

还是说我必须回收我创建的每个容器的内存,不回收就会引发泄露?
3430 次点击
所在节点    Python
9 条回复
cz5424
2020-12-05 19:02:39 +08:00
需要回收
ysc3839
2020-12-05 19:30:22 +08:00
我不熟悉 cython,以下说法是基于 ctypes 调用外部库。

> so 开辟的内存空间还受到 py 解释器控制吗
外部库分配的数据,一般是要调用外部库对应的释放函数来释放的,不受 Python 解析器控制。严格来说 Python 解析器都不关心这数据是什么。

> 所以我不需要手动回收容器的内存
是要的,除非你用 Python 类包装一下,然后在析构函数中释放。
fasionchan
2020-12-05 20:48:58 +08:00
如果你在 c 中申请内存(malloc),那么需要自己做好内存管理,该释放时就要释放(free),不然就是内存泄露。

如果你在 c 中创建 Python 对象,需要通过 Py_INCREF/Py_DECREF 这两个宏维护好引用计数,Python 虚拟机会根据引用计数决定什么时候释放内存。

那么什么时候需要调整引用计数呢?典型的场景包括:对象被添加到容器中,或者对象作为函数结果返回时等等。
如果引用计数维护不当,轻则内存泄露(该减没减),重则内存非法访问(该加没加)。
black11black
2020-12-06 08:18:40 +08:00
@ysc3839
@fasionchan
感谢回复,我是调用的 C++stl 的数据结构,用来对接 python 的列表,不是用 malloc 的形式,这种情况下要如何清理内存呢?
fasionchan
2020-12-06 08:31:43 +08:00
@black11black 一样的。如果你通过 new 创建了 c++对象,对象不用后要通过 delete 进行释放。如果通过类似智能指针的东西来管理,则遵守智能指针的约定即可,不用显式释放。
evilcoming
2020-12-06 08:46:15 +08:00
一般插件都会负责回收内存,如果插件没有回收,你要在插件源码中用 c 回收,而不是用 python 回收内存
black11black
2020-12-06 08:47:51 +08:00
@fasionchan 我做的主要操作是创建向量,map 之类的,然后向里面 push_back 数据。这种是否是类似智能指针的情况?我的合理处理方式是否是在使用完毕过后使用 vector.clear() ,然后想办法 delete 这个 vector,就可以确保不泄露?

另外我向 vector 里加入的不是类似 double 这种原生数据结构,而是 struct,这种情况下是否是每一个项目都要逐个删除,而 clear()不能统一释放?

谢谢
fasionchan
2020-12-06 09:43:40 +08:00
@black11black 第一个问题:你应该不是用智能指针,处理方式是对的。delete vector 其实就会执行 clear,所以 clear 不是必须的。

第二个问题,调用 clear 会对每个元素调用析构函数,析构函数函数一般就是用来释放资源的,因此无需逐个删除。如果你的 struct 引用了其他内存资源,例如 new 了什么其他对象,则需要在析构函数中将它 delete 。
sujin190
2020-12-07 11:42:23 +08:00
首先 cython 是个转译器不是编译器,更不是虚拟机运行时,所以 python 还是 python,c++还是 c++,该咋滴还咋滴啊

这是一个专为移动设备优化的页面(即为了让你能够在 Google 搜索结果里秒开这个页面),如果你希望参与 V2EX 社区的讨论,你可以继续到 V2EX 上打开本讨论主题的完整版本。

https://www.v2ex.com/t/732485

V2EX 是创意工作者们的社区,是一个分享自己正在做的有趣事物、交流想法,可以遇见新朋友甚至新机会的地方。

V2EX is a community of developers, designers and creative people.

© 2021 V2EX