【问题标题】:sys.getrefcount continuationsys.getrefcount 延续
【发布时间】:2010-10-20 01:58:48
【问题描述】:

link text

我明白了引用计数的概念

所以当我执行“del astrd”时,引用计数下降到零并且 astrd 被 gc 收集?

这是示例代码。这些代码是我根据昨天的问题开发的:link text

one.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 中所做的是否正确? 有没有不必要的步骤?如果有,为什么?

请帮我解决这个问题。

【问题讨论】:

    标签: python del


    【解决方案1】:

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

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

    至于原问题:

    • 当您执行del astrd 时,您会从本地命名空间中删除对对象的引用(无论是什么 asstrd 引用)的 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 = 测试() t.t = 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 个实例。

    【讨论】:

    • 我通过附加例如代码来编辑我的问题你能告诉我 wts hppng n 我正确吗?
    • 根据我昨天的问题,我试图删除我已附加第二个链接的导入
    • 您是否尝试从可能更改的 *.py 文件中执行代码?如果是这种情况,请查看 execfile。
    【解决方案2】:

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

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

    【讨论】:

      【解决方案3】:

      你能提供一些关于你在做什么的背景吗? 除了清理你不想暴露的东西的命名空间之外,很少有任何理由在变量上显式使用del。我不确定你为什么打电话给del file_name 或运行gc.collect()。 (del sys.modules[filename] 很好 - 这是 del 的不同用法)

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

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

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

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

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2011-10-30
        • 2012-10-14
        • 1970-01-01
        • 2016-03-28
        • 2010-10-14
        • 2012-05-08
        相关资源
        最近更新 更多