sys.getrefcount继续

时间:2009-04-17 10:28:16

标签: python del

link text

我得到了引用计数的概念

所以,当我执行“del astrd”时,引用计数会降为零,而ascd会被gc收集?

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

one.py:

def abc():

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

two.py:

import one
#reload(one)

#def defg():

one.abc()

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

请帮我解决这个问题。

3 个答案:

答案 0 :(得分:6)

我相信当refcount达到零时,内存会自动释放。 GC没有参与。

python GC是可选的,仅在存在具有引用周期的无法访问的对象时使用。实际上,如果您确定您的程序没有创建参考周期,则可以调用gc.disable()

至于原来的问题:

  • 执行del astrd时,删除astrd与本地命名空间的绑定对对象的引用(无论是什么astrd引用)。
  • 如果这意味着refcount为零,则释放该对象使用的内存。
  • 因此del不会删除对象,它会取消绑定引用。如果取消绑定引用会导致引用计数达到零,则删除对象会产生副作用。

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

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

import gc

class test(object):
    pass

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

for i in range(100):
    t = test()

print "Created and abandoned 100 instances, there are now", \
    number_of_test_instances(), \
    "instances known to the python interpreter."

# note that in normal operation, the GC would
# detect the unreachable objects and start
# collecting them right away
gc.disable()

for i in range(100):
    t = test()
    t.t = t

print "Created and abandoned 100 instances with circular ref, there are now", \
    number_of_test_instances(), \
    "instances known to the python interpreter."

gc.collect()
print "After manually doing gc.collect(), there are now", \
    number_of_test_instances(), \
    "instances known to the python interpreter."

运行此程序会给出:

Created and abandoned 100 instances, there are now 1 instances known to the python interpreter.
Created and abandoned 100 instances with circular ref, there are now 100 instances known to the python interpreter.
After manually doing gc.collect(), there are now 1 instances known to the python interpreter.

答案 1 :(得分:1)

在下一次GC集合运行中收集机会

请参阅:http://docs.python.org/library/gc.html

答案 2 :(得分:0)

你能否提供一些关于你在做什么的背景知识? 除了清理你不想公开的事物的命名空间之外,很少有任何理由在变量上显式使用del。我不确定您拨打del file_name或正在运行gc.collect()的原因。 (del sys.modules[filename]很好 - 这是del的另一种用法)

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

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

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

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