2

我试图理解 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?? "

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

编辑:为了回应martjin的第一个回复,我检查了以下内容

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

仍然不行:(我如何检查 a 是否被 gc 跟踪?

4

1 回答 1

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 对 -5 到 256 之间的值重复使用相同的int对象集。因此,a = 1不会创建要跟踪的新对象。您也不会看到任何其他原始类型。

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

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

于 2013-05-18T17:58:46.717 回答