I am trying to remove an object from memory in python and I am coming across an object that it is not being removed. From my understanding if there is no references to the object the garbage collector will de-allocate the memory when it is run. However after I have removed all of the references if I run
bar = Foo()
baz = gc.collect()
[< frame object at 0x7f1eba291e50>]
bar = [foo() for i in range(0, 10)]
for x in range(0,len(bar))
baz = bar[x]
import random, gc
def setPrev(self, object):
if random.random() > .90:
if self.p is not None and self.n is not None:
elif self.p is not None:
elif self.n is not None:
self.cells=[[Cell() for i in range(0,500)] for j in range(0,500)]
for x in range(0,100):
for y in range(0,100):
for z in range(0,100):
for x in range(0,500):
for y in range(0,500):
print " " + str(num) +" deleted today."
self.objects = None
self.objectsLast = None
def addObject(self, object):
if self.objects is None:
self.objects = object
self.objectsLast = object
current = self.objects
while current is not None:
current = current.getNext()
delete = current
current = current.getNext()
if delete.getPrev() is None:
self.objects = current
elif delete.getNext() is None:
self.objectsLast = delete.getPrev()
print "Building Map..."
x = Grid()
for y in range (1,101):
print "Simulating day " + str(y) +"..."
if __name__ == "__main__":
gc.get_referrers takes one argument: the object whose referers it should find.
I cannot think of any circumstance in which
gc.get_referrers would return no results, because in order to send an object to
gc.get_referrers, there has to be a reference to the object.
In other words, if there was no reference to the object, it would not be possible to send it to
At the very least, there will be a reference from the
globals() or from the current execution frame (which contains the local variables):
A code block is executed in an execution frame. An execution frame contains some administrative information (used for debugging), determines where and how execution continues after the code block's execution has completed, and (perhaps most importantly) defines two namespaces, the local and the global namespace, that affect execution of the code block.
See an extended version of the example from the question:
class Foo(object): pass def f(): bar = [Foo() for i in range(0, 10)] for x in range(0, len(bar)): # at this point there is one reference to bar[x]: it is bar print len(gc.get_referrers(bar[x])) # prints 1 baz = bar[x] # at this point there are two references to baz: # - bar refernces it, because it is in the list # - this "execution frame" references it, because it is in variable "baz" print len(gc.get_referrers(bar[x])) # prints 2 del bar[x] # at this point, only the execution frame (variable baz) references the object print len(gc.get_referrers(baz)) # prints 1 print gc.get_referrers(baz) # prints a frame object del baz # now there are no more references to it, but there is no way to call get_referrers f()
There is a better trick to detect whether there are referers or not:
weakref module provides a way to create weak references to an object which do not count. What it means is that even if there is a weak reference to an object, it will still be deleted when there are no other references to it. It also does not count in the
>>> x = Foo() >>> weak_x = weakref.ref(x) >>> >>> gc.get_referrers(x) == [globals()] # only one reference from global variables True >>> x <__main__.Foo object at 0x000000000272D2E8> >>> weak_x <weakref at 0000000002726D18; to 'Foo' at 000000000272D2E8> >>> del x >>> weak_x <weakref at 0000000002726D18; dead>
The weak reference says that the object is dead, so it was indeed deleted.