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



我正在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:我没有找到对堆进行碎片整理的方法,但能够使用内存分析器(我最喜欢的)和堆积来定位问题。我通过缩小向量并将数据类型更改为整数(而不是浮点数)来解决这个问题。我怀疑我用来存储/加载矢量的 cPickle 模块在使用浮点数时内存泄漏,这就是我内存不足的原因。

您应该使用内存探查器。

推荐使用哪种 Python 内存分析器?

memory_profiler

PySizer

道瑟

甚至是对象图库

最新更新