许多Cython STL测试看起来像这样:
def simple_test(double x):
"""
>>> simple_test(55)
3
"""
v = new vector[double]()
try:
v.push_back(1.0)
v.push_back(x)
from math import pi
v.push_back(pi)
return v.size()
finally:
del v
那里是否需要del
语句,或者Python的/ Cython的引用计数是否适用于我们?
答案 0 :(得分:1)
您需要del
因为vector
不是python类。
有许多因素使得pythons垃圾收集器无法收集该对象:
vector
个实例没有reference-count属性,因为它们的类/结构不包含PyObject_HEAD
。这是一个C(C ++)类,为什么会这样呢?
Python对象使用PyObject_GC_New
使垃圾收集器知道其实例,并PyObject_GC_Del
(或PyObject_GC_UnTrack
)进行删除。但是vector
使用new
进行创建(在堆上),因此垃圾收集器根本不涉及 ,因此您需要一个明确的del
(我认为) delete
也应该有效,但我没有检查过)。
这也可以在源代码中看到(我使用ipythons %%cython
,因此示例是可重现的):
%%cython --cplus
from libcpp.vector cimport vector
def simple_test(double x):
v = new vector[double]()
try:
v.push_back(1.0)
v.push_back(x)
from math import pi
v.push_back(pi)
return v.size()
finally:
del v
在.cpp
文件中提供以下(极端)缩短的代码(通常此文件位于主目录的.ipython/cython
文件夹中):
/* "_cython_magic_9df9dbf5f4981f282eb46337245f3bb9.pyx":9
* 3
* """
* v = new vector[double]() # <<<<<<<<<<<<<<
* try:
* v.push_back(1.0)
*/
try {
__pyx_t_1 = new std::vector<double> ();
} catch(...) {
[...]
}
__pyx_v_v = __pyx_t_1;
/* "_cython_magic_9df9dbf5f4981f282eb46337245f3bb9.pyx":17
* return v.size()
* finally:
* del v # <<<<<<<<<<<<<<
*/
[...]
{
delete __pyx_v_v;
}
因此,如果没有del v
,则不会有delete
语句,您可能(可能)在代码中出现内存泄漏。
%%cython --cplus
from libcpp.vector cimport vector
def simple_test(double x):
v = new vector[double]()
for _ in range(20000000):
v.push_back(x)
return v.size()
# NO "del"!!!
import psutil
for _ in range(10):
simple_test(10)
print(psutil.virtual_memory().percent)
打印哪些:
47.5
49.4
51.2
53.1
55.1
57.0
58.9
60.8
62.8
65.0
66.9
68.9
70.6
72.5
74.5
76.4
78.4
80.3
82.2
83.6
因此,至少在我的计算机上,这导致内存使用量不断增加,而del
的内存使用不会:
%%cython --cplus
from libcpp.vector cimport vector
def simple_test(double x):
v = new vector[double]()
try:
for _ in range(20000000):
v.push_back(x)
return v.size()
finally:
del v # this one has a del statement!!!
import psutil
for _ in range(20):
simple_test(10)
print(psutil.virtual_memory().percent)
结果:
47.4
47.4
47.4
47.4
47.4
47.4
47.4
47.4
47.2
47.2
47.2
47.2
47.2
47.2
47.2
47.2
47.2
47.2
47.2
47.3