运行功能后强制释放内存

时间:2019-09-20 10:46:24

标签: python python-3.x

我使用的模块(我无法修改)包含我需要使用的方法。此方法返回10GB的数据,但还会分配8GB不会释放的内存。我需要在运行很长时间的脚本的开头使用此方法,并且我想确保在运行该方法后释放8GB的内存。我在这里有什么选择?

请注意,脚本不会重复使用8GB的内存-即,如果我在运行该方法后创建了一个大型numpy数组,则会为该numpy数组分配额外的内存。

我曾考虑过使用多处理模块在一个单独的进程中运行该方法(并返回结果),但是在序列化该方法的大型结果时遇到了问题-默认的pickler无法腌制10GB,即使我强制使用腌制版本4的多处理腌制具有非常大的内存开销。在没有修改有问题的模块的情况下我还能做些其他事情吗?

编辑:这是一个示例

from dataloader import dataloader1
result = dataloader1.get("DATA1")

据我了解,数据加载器是使用pybind11围绕某些C ++代码的Python包装器。我对其内部运作一无所知。上面的代码导致使用18GB。如果我再跑

del result

已正确释放10GB,但继续使用8GB(似乎不再存在python对象)。

Edit2:如果我创建一个较小的numpy数组(例如3GB),则内存使用率将保持在8GB。如果删除它,而是创建一个6GB的numpy数组,则内存使用量将达到14GB,并在删除后降至8GB。我仍然需要发布到操作系统的8GB。

3 个答案:

答案 0 :(得分:2)

您可以修改功能吗? 如果内存由某个模块保留,请尝试重新加载该模块(importlib.reload),这将释放内存。

答案 1 :(得分:0)

Python使用2种不同的机制来释放内存。

  1. Reference Counting,主要使用该方法,并在不再需要内存时(例如,对象从作用域中丢失)立即释放内存。

  2. Garbage Collector,它是次要的,用于收集具有循环引用(a -> b -> c -> a)的对象。可以使用method来触发。否则,Python本身将决定何时释放内存。

但是,我强烈建议对代码进行概要分析和修改,以免占用太多内存。也许调查流,或使用数据库。

答案 2 :(得分:0)

如果内存不是由gc释放的,则可能是因为对象存储在创建它的类中,所以一种选择是在类中(通过概要分析)查找该大属性是什么并为其分配它到None可能会导致gc释放内存。