How can I explicitly free memory in Python?
我编写了一个python程序,它作用于一个大的输入文件,创建数百万个表示三角形的对象。算法是:
off的要求是在打印出三角形之前打印出完整的顶点列表,这意味着在将输出写入文件之前,必须在内存中保存三角形列表。同时,由于列表的大小,我得到了内存错误。
告诉python我不再需要某些数据,并且可以释放这些数据,最好的方法是什么?
根据python官方文档,您可以使用
1 2 | import gc gc.collect() |
不幸的是(取决于您的版本和python的发行版),某些类型的对象使用"空闲列表",这是一种整洁的本地优化,但可能会导致内存碎片化,特别是通过使越来越多的内存"专用于"特定类型的对象,从而不可用于"一般资金"。
确保大量但暂时使用内存的唯一真正可靠的方法是在系统完成后将所有资源返回给系统,这是在子进程中进行的,而子进程则会终止消耗内存的工作。在这种情况下,操作系统将完成它的工作,并欣然回收子进程可能已经占用的所有资源。幸运的是,
在您的用例中,子流程积累一些结果并确保这些结果对主流程可用的最好方法似乎是使用半临时文件(我的意思是,半临时文件,不是关闭时自动消失的文件,而是在完成所有操作后显式删除的普通文件他们)
我听说Linux和Unix类型的系统上有人用一个python进程来做一些工作,获取结果,然后杀死它。
本文对Python垃圾收集器有一些说明,但我认为缺乏内存控制是托管内存的缺点。
python是垃圾收集的,因此如果减少列表的大小,它将回收内存。您还可以使用"del"语句完全消除变量:
1 2 3 | biglist = [blah,blah,blah] #... del biglist |
您不能显式释放内存。您需要做的是确保不保留对对象的引用。然后它们将被垃圾收集,释放内存。
在您的例子中,当您需要大列表时,通常需要重新组织代码,通常使用生成器/迭代器。这样你就不需要在内存中有大的列表了。
http://www.prasanatech.net/2009/07/introduction-python-generators.html
(
也许您一开始不会遇到任何内存问题,因为您的数据使用了更紧凑的结构。因此,与标准
其他人已经发布了一些方法,您可以"哄骗"Python解释器释放内存(或者避免出现内存问题)。很可能你应该先试试他们的想法。不过,我觉得直接回答你的问题很重要。
实际上没有任何方法可以直接告诉Python释放内存。事实上,如果你想要低水平的控制,你就必须在C或C++中写一个扩展。
也就是说,有一些工具可以帮助实现这一点:
- 赛隆
- 斯威格
- 增强Python
我在从文件中读取图表时遇到了类似的问题。处理过程包括计算一个不适合内存的200 000×200 000浮点矩阵(一次一行)。尝试在使用
为了解决内存和性能问题,我改用了在某个地方读过一次的多线程技巧(对不起,我再也找不到相关的帖子了)。在我在一个大的
实际上,它是这样工作的:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 | from dask import delayed # this module wraps the multithreading def f(storage, index, chunk_size): # the processing function # read the chunk of size chunk_size starting at index in the file # process it using data in storage if needed # append data needed for further computations to storage return storage partial_result = delayed([]) # put into the delayed() the constructor for your data structure # I personally use"delayed(nx.Graph())" since I am creating a networkx Graph chunk_size = 100 # ideally you want this as big as possible while still enabling the computations to fit in memory for index in range(0, len(file), chunk_size): # we indicates to dask that we will want to apply f to the parameters partial_result, index, chunk_size partial_result = delayed(f)(partial_result, index, chunk_size) # no computations are done yet ! # dask will spawn a thread to run f(partial_result, index, chunk_size) once we call partial_result.compute() # passing the previous"partial_result" variable in the parameters assures a chunk will only be processed after the previous one is done # it also allows you to use the results of the processing of the previous chunks in the file if needed # this launches all the computations result = partial_result.compute() # one thread is spawned for each"delayed" one at a time to compute its result # dask then closes the tread, which solves the memory freeing issue # the strange performance issue with gc.collect() is also avoided |
如果不关心顶点重用,可以有两个输出文件——一个用于顶点,一个用于三角形。完成后,将三角形文件附加到顶点文件。