2

链接文本

我得到了引用计数的概念

因此,当我执行“del astrd”时,引用计数降至零并且 astrd 被 gc 收集?

这是示例代码。我在昨天的问题之后开发的这些代码:链接文本

一个.py:

定义 abc():

print "Hello"
print "123"
print '345'

二.py:

import one
#reload(one)

#def defg():

one.abc()

三.py:

import os,sys,gc
from time import sleep

import two
#reload(two)
#two.defg()

sleep(20)


directory = os.listdir('.')

for filename in directory:

        if filename[-3:] == 'pyc':

                print '- ' + filename

                print sys.getrefcount(filename)

                file_name = os.path.splitext (filename)[0]

                del file_name   # remove the local reference

                del sys.modules[os.path.splitext (filename)[0]] # removes import

                gc.collect()    # garbage collect

                #del sys.modules[filename]

                #del filename

                #os.remove(filename)

我在three.py 中所做的是否正确?是否有任何不必要的步骤?如果是,为什么?

请帮我解决这个问题。

4

3 回答 3

8

我相信内存会在 refcount 达到零的那一刻自动释放。GC 不参与。

python GC 是可选的,仅在存在具有引用周期的不可访问对象时使用。事实上,gc.disable()如果您确定您的程序不会创建引用循环,则可以调用。

至于原来的问题:

  • 当你这样做时del astrd,你会从本地命名空间中删除对对象的引用(无论 asstrd 引用什么)的绑定。
  • 如果这意味着引用计数为零,则释放对象使用的内存。
  • 所以del不会删除对象,它会取消绑定引用。如果取消绑定引用导致引用计数达到零,则删除对象是一种副作用。

请注意,上述内容仅适用于 CPython。我相信 Jython 和 IronPython 使用 JVM/CLR GC 机制,根本不使用引用计数。

方便gc.get_objects返回 python 解释器跟踪的所有对象实例的列表。例子:

导入 gc

类测试(对象):
    经过

def number_of_test_instances():
    return len([obj for obj in gc.get_objects() if isinstance(obj, test)])

对于范围内的我(100):
    t = 测试()

print "创建和放弃100个实例,现在有", \
    number_of_test_instances(), \
    “python 解释器已知的实例。”

# 请注意,在正常操作中,GC 会
# 检测不可达对象并启动
# 立即收集它们
gc.disable()

对于范围内的我(100):
    t = 测试()
    tt = t

print "用循环引用创建和放弃了 100 个实例,现在有", \
    number_of_test_instances(), \
    “python 解释器已知的实例。”

gc.collect()
print "手动执行 gc.collect() 后,现在有", \
    number_of_test_instances(), \
    “python 解释器已知的实例。”

运行这个程序给出:

创建和放弃 100 个实例,现在有 1 个实例为 Python 解释器所知。
使用循环引用创建和放弃 100 个实例,现在有 100 个实例为 Python 解释器所知。
手动执行 gc.collect() 后,python 解释器现在知道 1 个实例。
于 2009-04-17T10:50:02.147 回答
1

它有机会在下一次 GC 收集运行时被收集。

见:http ://docs.python.org/library/gc.html

于 2009-04-17T10:32:41.563 回答
1

你能提供一些关于你在做什么的背景吗?del除了清理您不想公开的事物的名称空间之外,很少有任何理由显式使用on 变量。我不确定你为什么打电话del file_name或跑步gc.collect()。(del sys.modules[filename]很好 - 这是 del 的不同用法)

对于对象,当它们最终确定的确切时间无关紧要时(例如,像 file_name 这样的字符串),您也可以让变量退出范围 - 当您的函数完成时,它将被收集,并且不会造成任何伤害直到那时。手动调用del此类变量只会使您的代码混乱。

对于需要立即完成的对象(例如打开的文件或持有的锁),无论如何您都不应该依赖垃圾收集器 - 不能保证立即收集这些对象。它恰好在标准 C python 实现中这样做,但在 Jython 或 IronPython 中没有,因此不能保证。close相反,您应该通过调用或使用 newwith构造来显式清理此类对象。

唯一的另一个原因可能是您分配了非常大量的内存,并且希望在引用它的变量自然超出范围之前发出信号您已经完成了它。

但是,您的示例似乎不适合这两种情况,所以我不确定您为什么要手动调用垃圾收集器。

于 2009-04-17T16:04:25.603 回答