Python:破解gc之谜

时间:2013-05-18 17:55:36

标签: python garbage-collection python-2.6

我正在尝试理解gc,因为我在一个程序中有一个大的列表,我需要删除它以释放一些急需的内存。我想回答的基本问题是how can I find what is being tracked by gc and what has been freed?以下是说明我的问题的代码

import gc
old=gc.get_objects()
a=1
new=gc.get_objects()
b=[e for e in new if e not in old]
print "Problem 1: len(new)-len(old)>1 :", len(new), len(old)
print "Problem 2: none of the element in b contain a or id(a): ", a in b, id(a) in b
print "Problem 3: The reference counts are insanely high, WHY?? "

恕我直言,这是docs中没有解决的奇怪行为。对于初学者,为什么分配单个变量会为gc创建多个条目?为什么它们都不是我做的变量?我在get_objects()中创建的变量的条目在哪里?

编辑:为了回应马丁的第一次回应,我检查了以下内容

a="foo"
print a in gc.get_objects()

仍然不行:(我如何检查gc正在跟踪a?

1 个答案:

答案 0 :(得分:2)

gc.get_objects()的结果本身未被跟踪;否则会产生一个循环引用:

>>> import gc
>>> print gc.get_objects.__doc__
get_objects() -> [...]

Return a list of objects tracked by the collector (excluding the list
returned).

您没有看到a列出,因为它引用了一个低整数单例。 Python重复使用相同的int个对象集,其值介于-5到256之间。因此,a = 1不会创建要跟踪的新对象。你也不会看到任何其他原始类型。

CPython垃圾收集只需跟踪容器类型,可以引用其他值的类型,因为GC需要做的唯一事情就是打破循环引用。

请注意,在任何Python脚本启动时,已经运行了一些自动代码。 site.py设置你的Python路径,例如,涉及列表,映射等。然后有上面提到的memoized int值,CPython还缓存tuple()个对象以供重用,等等结果,在启动时,在代码的一行开始之前,很容易有5k +对象存活。