and*_*chy 5 python memory garbage-collection numpy out-of-memory
在迭代 30 个涉及内存和 CPU 密集型数值计算的问题序列的 Python 代码中,我观察到 Python 进程的内存消耗在 30 次迭代中每次开始时都会增加约 800MB,并最终MemoryError引发第 8 次迭代(系统内存实际上已耗尽)。但是,如果我在每次迭代后import gc运行gc.collect(),那么内存消耗将保持在约 2.5GB 不变,并且 Python 代码在解决所有 30 个问题后会很好地终止。该代码仅使用连续2个问题的数据,并且没有引用周期(否则手动垃圾收集也无法降低内存消耗)。
如果 Python 尝试在引发MemoryError. 在我看来,这将是一件完全理智的事情,但也许有理由反对这样做?
此处进行了与上述类似的观察:https ://stackoverflow.com/a/4319539/1219479
实际上,存在引用循环,这是手动gc.collect()调用能够回收内存的唯一原因。
在 Python 中(我假设是 CPython),垃圾收集器的唯一目的是打破引用循环。当不存在时,对象将被销毁,并在最后一次对它们的引用丢失时回收它们的内存。
至于垃圾收集器何时运行,完整文档位于: http: //docs.python.org/2/library/gc.html
最重要的是,Python 维护一个对象分配和释放的内部计数器。每当(allocations - deallocations)达到 700(阈值 0)时,就会运行垃圾收集,并且两个计数器都会重置。
每次发生收集(自动或手动运行gc.collect())时,都会收集第 0 代(尚未在收集中幸存的所有对象)(即,遍历没有可访问引用的对象,寻找引用循环 -如果找到任何一个,循环就会被破坏,可能会导致对象被销毁,因为没有留下任何引用)。该集合之后剩余的所有对象都将移至第 1 代。
每 10 次收集(阈值 1),第 1 代也会被收集,并且第 1 代中存活下来的所有对象都会移动到第 2 代。第 1 代的每 10 个收集(即每 100 个收集 - 阈值 2),第 2 代也被收集。幸存下来的对象留在第 2 代中——没有第 3 代。
用户可以通过调用 来设置这 3 个阈值gc.set_threshold(threshold0, threshold1, threshold2)。
这一切对您的程序意味着什么:
MemoryError引发之前运行。|   归档时间:  |  
           
  |  
        
|   查看次数:  |  
           2832 次  |  
        
|   最近记录:  |