如何在Python中进行垃圾回收。有人说它是自动发生的。但是,正确的过程是什么?
答案 0 :(得分:0)
了解 Python 垃圾收集的内部原理,以及 Instagram 工程师如何通过调整将其性能提升 10%。
答案 1 :(得分:-1)
Python内存管理简介
Python的内存分配和释放方法是自动的。用户不必像使用C或C ++这样的语言使用动态内存分配时那样,就必须手动预先分配或取消分配内存。 Python使用两种策略进行内存分配引用计数和垃圾回收。
在Python 2.0版之前,Python解释器仅将引用计数用于内存管理。引用计数是通过计算一个对象被系统中其他对象引用的次数来进行的。删除对对象的引用后,该对象的引用计数将减少。当引用计数变为零时,对象将被释放。
引用计数非常有效,但确实有一些警告。这样的警告之一是它无法处理参考周期。参考周期是指无法到达对象但其参考计数仍大于零的情况。创建引用循环的最简单方法是创建一个引用自身的对象,如下例所示:
def make_cycle():
1 = [ ]
1.append(l)
make_cycle()
因为make_cycle()创建了一个引用自身的对象1,所以该函数返回时不会自动释放该对象1。这将导致1所使用的内存被保留,直到调用Python垃圾收集器为止。
自动垃圾回收循环
由于参考周期需要进行计算工作才能发现,因此垃圾回收必须是计划的活动。 Python根据对象分配和对象释放的阈值调度垃圾回收。当分配数减去取消分配数大于阈值数时,将运行垃圾收集器。可以通过加载gc模块并询问垃圾收集阈值来检查新对象(在Python中称为0代对象的对象)的阈值:
import gc
print "Garbage collection thresholds: %r" % gc.get_threshold()
Garbage collection thresholds: (700, 10, 10)
在这里,我们可以看到上述系统的默认阈值为700。这意味着,当分配数与释放数之比大于700时,将运行自动垃圾收集器。
如果您的Python设备内存不足,自动垃圾收集将不会运行;相反,您的应用程序将引发异常,必须对其进行处理,否则应用程序将崩溃。由于自动垃圾收集对NUMBER个免费对象(而不是它们的大小)具有较高的权重,这一事实使情况更加恶化。因此,代码中释放大量内存块的任何部分都是运行手动垃圾回收的理想选择。
手动垃圾收集
对于某些程序,尤其是长时间运行的服务器应用程序或在Digi Device上运行的嵌入式应用程序,自动垃圾回收可能不够。尽管编写应用程序时应尽量避免引用周期,但最好有一个策略来处理它们。在程序执行的适当时机手动调用垃圾收集器可以很好地了解如何处理参考周期消耗的内存。
可以通过以下方式手动调用垃圾回收:
import gc
gc.collect()
gc.collect()返回它已收集并释放的对象数。您可以通过以下方式打印此信息:
import gc
collected = gc.collect()
print "Garbage collector: collected %d objects." % (collected)
如果我们创建几个周期,我们可以看到手动收集工作:
import sys, gc
def make_cycle():
1 = { }
1[0] = 1
def main():
collected = gc.collect()
print "Garbage collector: collected %d objects." % (collected)
print "Creating cycles..."
for i in range(10):
make_cycle()
collected = gc.collect()
print "Garbage collector: collected %d objects." % (collected)
if __name__ == "__main__":
ret = main()
sys.exit(ret)
通常,有两种建议的策略用于执行手动垃圾收集:基于时间的垃圾收集和基于事件的垃圾收集。基于时间的垃圾收集很简单:在固定的时间间隔调用垃圾收集器。基于事件的垃圾收集会在事件上调用垃圾收集器。例如,当用户断开与应用程序的连接或已知应用程序进入空闲状态时。
参考: