views:

259

answers:

4
class example:

    def exampleMethod(self):
        aVar = 'some string'
        return aVar

In this example, how does garbage collection work after each call to example.exampleMethod()? Will aVar be deallocated once the method returns?

+5  A: 

The variable is never deallocated.

The object (in this case a string, with a value of 'some string' is reused again and again, so that object can never be deallocated.

Objects are deallocated when no variable refers to the object. Think of this.

a = 'hi mom'
a = 'next value'

In this case, the first object (a string with the value 'hi mom') is no longer referenced anywhere in the script when the second statement is executed. The object ('hi mom') can be removed from memory.

S.Lott
I don't think your second paragraph is clear enough; perhaps you should clarify that 'some string' stays allocated because it's a constant in the code object of the method, so it's referenced and it stays in memory while the method exists (typically, until the end of the process).
ΤΖΩΤΖΙΟΥ
+3  A: 

Every time You assign an object to a variable, You increase this object's reference counter.

a = MyObject() # +1, so it's at 1
b = a # +1, so it's now 2
a = 'something else' # -1, so it's 1
b = 'something else' # -1, so it's 0

Noone can access this the MyObject object We have created at the first line anymore.

When the counter reaches zero, the garbage collector frees the memory.

There is a way to make a tricky reference that does not increase reference counter (f.e. if You don't want an object to be hold in memory just because it's in some cache dict).

More on cPython's reference counting can be found here.

Python is language, cPython is it's (quite popular) implementation. Afaik the language itself doesn't specify how the memory is freed.

Reef
+3  A: 

From your example, if you call example.exampleMethod() , without assigning the results (eg. a = example.exampleMethod()) then it will be deallocated straight away (in CPython), as CPython uses a reference counting mechanism. Strings aren't a very good example to use, because they also have a number of implementation specific optimizations. Strings can be cached, and are not deallocated so that they can be reused. This is especially useful because strings are very common for use as keys in dicts.

Again, garbage collecting is specific to the implementations, so CPython, Jython and IronPython will have different behaviours, most of these being documented on the respective sites/manuals/code/etc. If you want to explore a bit, I'd suggest creating a class where you have defined the del() method, which will be called upon the object being garbage collected (it's the destructor). Make it print something so you can trace it's call :)

Nico
A: 

As in Nico's answer, it depends on what you do with the result returned by exampleMethod. Python (or CPython anyway) uses reference counting. During the method, aVar references the string, while after that the variable aVar is deleted, which may leave no references, in which case, it is deleted.

Below is an example with a custom class that has a destructor (del(self), that print out "Object 1 being destructed" or similar. The gc is the garbage collector module, that automatically deletes objects with a reference count of 0. It's there for convenience, as otherwise there is no guarantee when the garbage collector is run.

import gc
class Noisy(object):
    def __init__(self, n):
        self.n = n
    def __del__(self):
        print "Object " + str(self.n) + " being destructed"  
class example(object):
    def exampleMethod(self, n):
        aVar = Noisy(n)
        return aVar
a = example()
a.exampleMethod(1)
b = a.exampleMethod(2)
gc.collect()
print "Before b is deleted"
del b
gc.collect()
print "After b is deleted"

The result should be as follows:

Object 1 being destructed
While b lives
Object 2 being destructed
After b is deleted

Notice that the first Noisy object is deleted after the method is returned, as it is not assigned to a variable, so has a reference count of 0, but the second one is deleted only after the variable b is deleted, leaving a reference count of 0.

Silverfish