sys.getrefcount continuation
Asked Answered
G

3

2

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.

Gca answered 17/4, 2009 at 10:28 Comment(0)
B
8

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.
Belongings answered 17/4, 2009 at 10:50 Comment(3)
m editing my question by attaching an eg code can u tell me wts hppng n am i correct ?Gca
As per my yesterday's question i was trying to delete the imports I have attached the second linkGca
Are you trying to execute code from *.py files that may change? If that is the case, have a look at execfile.Belongings
I
1

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

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

Incipit answered 17/4, 2009 at 10:32 Comment(0)
M
1

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.

Moquette answered 17/4, 2009 at 16:4 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.