When Are Objects Garbage Collected in Python

When are objects garbage collected in python?

Here is an excerpt from the language reference

Objects are never explicitly destroyed; however, when they become unreachable they may be garbage-collected. An implementation is allowed to postpone garbage collection or omit it altogether — it is a matter of implementation quality how garbage collection is implemented, as long as no objects are collected that are still reachable.

CPython implementation detail: CPython currently uses a reference-counting scheme with (optional) delayed detection of cyclically linked garbage, which collects most objects as soon as they become unreachable, but is not guaranteed to collect garbage containing circular references. See the documentation of the gc module for information on controlling the collection of cyclic garbage. Other implementations act differently and CPython may change. Do not depend on immediate finalization of objects when they become unreachable (ex: always close files).

EDIT: About postponing garbage collection .... the gc module allows you to interact with the garbage collector, and disable it if you want to and change collection frequency etc. But I have not used it myself. Also, cycles that contain any objects with __del__ methods are not collected.

How to give object away to python garbage collection?

I find that most programs create and dispose of objects quite naturally, so I never normally worry about it.

Some examples:

person = Person('john')
person = Person('james')
# Whoops! 'john' has died!

people = []
people.append(Person('john'))
# ...
# All 'Persons' live in people
people = []
# Now all 'Persons' are dead (including the list that referenced them)

class House():
def setOwner(self, person):
self.owner = person

house.setOwner(people[0])
# Now a House refers to a Person
people = []
# Now all 'Persons' are dead, except the one that house.owner refers to.

What I assume you are after is this:

people = {}
people['john'] = Person('john')

def removePerson(personName):
del people[personName]

removePerson('john')

In this case people is the master list and you can control when a Person gets added and removed from the list (its a dictionary).

You may have to think through the concept of a person being created and then dying very thoroughly: Once created how does the person first interact with the simulation. Upon death, how should you untangle the references? (Its ok for a person to refer to other stuff, its things like House in my example that would keep a person alive. You could have other objects hold on to just the name of the person).

When exactly do overwritten variables get garbage collected?

When data is no longer reachable the Python garbage collector, in the background, marks the memory as being available for subsequent allocations. It doesn't get freed with respect to the kernel, however.

If what you care about is when the physical memory is made available to other processes by the kernel, that's another thing: the memory is still virtually mapped into your Python process' address space, so in order for that physical memory to be freed by the kernel, either your Python process has to exit (thus freeing all of the physical memory allocated to it), or the physical memory formerly holding your data needs to become least recently used according to the kernel's virtual memory policy. If there are no other processes competing for it (likely in a multi-gigabyte system), that could take a long time. If there are other processes competing for physical memory, it could happen in a number of seconds or minutes. Further, if your Python process allocates any more data, all of a sudden those pages are recently used again, so become last-in-line for physical reclamation. If you're that low on physical memory, though, your system is probably having other issues.

When are return values garbage collected?

Try explicitly calling del on the returned value:

returned_value = fun()
del returned_value

But finalizers like __del__ can be problematic; as you have already seen, one issue is that when they get called is not deterministic. Also, it is possible within a finalizer to reinstantiate a deleted object, such as sticking a reference to it in a global list.

If you need to release resources (besides just raw memory) - things like unlocking locks, closing files, or releasing database connections, use a context manager, and bound its life span using the with statement. Many of these resource are already context managers. For example, a threading.Lock can be locked and unlocked implicitly using with:

# "with" statement will call the __enter__ method of self.lock,
# which will block until self.lock can be locked
with self.lock:
# do thread-synchronized stuff here

# self.lock is automatically released here - at then end of
# the "with" block, the lock's __exit__ method is called, which
# releases the lock. This will get called even if the block is
# exited by a raised exception

When are python objects candidates for garbage collection?

The variable will be eligible for garbage collection as soon as all references to it go out of scope or are manually deleted (del x).

In your example, foo must exist before this line (otherwise it's a NameError), and therefore will never be garbage collected in your example block of code, as the reference will still exist after this. Even if one were to call del foo after this, we would have to presume there were no references to the object anywhere else for it to be garbage collected.

How does garbage collection in Python work with class methods?

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.



Related Topics



Leave a reply



Submit