我可以在 Python 脚本中对堆进行碎片整理吗?

Can I defragment the heap in a Python script?

我正在 Python 中运行恶意软件分析实验,我需要创建一个大对象(我认为是 512 MB)。在本地(64 位系统)测试时没有问题,但是当我尝试在远程 32 位系统上运行它时(因此进程的堆栈最大为 4 GB),我得到一个 MemoryError(堆栈跟踪没有提供太多信息)。大分配是:

from sklearn.grid_search import GridSearchCV
...
model = GridSearchCV(svm.LinearSVC(), {'C':numpy.logspace(-3,3,7)})
model.fit(train_vectors, labels)

我问过系统管理员,他告诉我可能是之前的分配把堆碎片化了,所以大分配已经不可能了。

我尝试在导致大量分配的调用之前运行 gc.collect(),但问题仍然存在。

我不认为有办法让大分配变小。

关于如何对堆进行碎片整理有什么建议吗?

编辑:我设法使训练向量小了很多。现在我需要看看恶意软件检测技术是否仍然有效。如果是这样,我的问题应该得到解决。原因是向量是 numpy 数组,仅使用函数 tolist() 使它们变小了很多。

编辑 2:仅使用(浮点数)列表是不够的。因为这些值无论如何都是整数,所以我将浮点数转换为整数,使向量更小一些。这对内存使用有很大影响。我使用 cPickle 保存向量并使用相同的模块检索它们。我猜该模块中某处存在一个错误,该错误会在加载浮点数时导致内存,而整数则不存在。

TL;DR:我没有找到对堆进行碎片整理的方法,但能够使用内存分析器(我最喜欢它)和堆来定位问题。我通过缩小向量并将数据类型更改为整数(而不是浮点数)来解决问题。我怀疑我用来 store/load 向量的 cPickle 模块在使用浮点数时有内存泄漏,这就是我内存不足的原因。

您应该使用内存分析器。

来自 Which Python memory profiler is recommended? :

Heapy

memory_profiler

PySizer

Dowser

甚至 objgraph library