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
Importing from a Relative Path in Python
Plotting 3D Polygons in Python-Matplotlib
A Fast Way to Find the Largest N Elements in an Numpy Array
Selenium Element Not Visible Exception
How to Fix "Importerror: No Module Named ..." Error in Python
Python Accessing Nested JSON Data
Check If a Process Is Running or Not on Windows
Elegant Way to Check If a Nested Key Exists in a Dict
How to Stop Flask from Initialising Twice in Debug Mode
How to Convert a Timezone Aware String to Datetime in Python Without Dateutil
Pandas Create New Column with Count from Groupby
Why 'Torch.Cuda.Is_Available()' Returns False Even After Installing Pytorch with Cuda
Efficient Numpy 2D Array Construction from 1D Array
How to Get the Nth Element of a Python List or a Default If Not Available