sys.getrefcount continuation

无人久伴 提交于 2019-12-09 02:04:29

问题


link text

I got the concept of reference count

So when i do a "del astrd" ,reference count drops to zero and astrd gets collected by gc ?

This is the sample codes.These codes I developed after my yesterday's question: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)

What i did in three.py is correct or not ? Is there any unnecessary step ?If yes,why ?

Please help me out of this.


回答1:


I believe that memory is automatically freed the moment the refcount reaches zero. The GC is not involved.

The python GC is optional, and is only used when there are unreachable objects that has reference cycles. In fact, you can call gc.disable() if you are sure your program does not create reference cycles.

As for the original question:

  • When you do del astrd, you remove the binding of astrd from the local namespace a reference to an object (whatever astrd references).
  • If this means that the refcount is zero, the memory used by the object is freed.
  • So del does not delete objects, it unbinds references. The deletion of objects is a side effect that occurs if unbinding a reference causes the refcount to reach zero.

Note that the above is only true for CPython. Jython and IronPython uses the JVM/CLR GC mechanism, and does not use refcounting at all, I believe.

The handy gc.get_objects returns a list of all object instances tracked by the python interpreter. Example:

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."

Running this program gives:

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.



回答2:


It gets a chance to get collected on the next GC collection run.

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




回答3:


Could you give some background as to what you are doing? There's rarely any reason for explicitly using del on variables other than to clean up a namespace of things you don't want to expose. I'm not sure why you are calling del file_name or running gc.collect(). (del sys.modules[filename] is fine - that's a different use of del)

For objects when the exact time they get finalised doesn't matter (eg strings like file_name), you may as well let the variable drop out of scope - when your function finishes, it will be collected, and it won't cause any harm till then. Manually calling del for such variables just clutters up your code.

For objects which need to be finalised immediately (eg. an open file, or a held lock), you shouldn't be relying on the garbage collector anyway - it is not guaranteed to immediately collect such objects. It happens to do so in the standard C python implementation, but not in Jython or IronPython, and is so not guaranteed. Instead, you should explicitly clean up such objects by calling close or using the new with construct.

The only other reason might be that you have a very large amount of memory allocated, and want to signal you are done with it before the variable that refers to it goes out of scope naturally.

Your example doesn't seem to fit either of these circumstances however, so I'm not sure why you're manually invoking the garbage collector at all.



来源:https://stackoverflow.com/questions/759906/sys-getrefcount-continuation

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!