Variables are memory references.
my_var=10
this is stored in the one of the memory slots. my_var
actually references the address of the memory slot where the 10 is stored. if you type:
id(my_var)
you will get the address of the slot in base-10. hex(id(my_var) )
will give the hex representation of the address.
Whenever we use my_var
python memory manager goes to the memory and retrieves the value of 10. Python memory manager also keeps track of the number of references for this memory slot. if there is no reference to this memory address, python memory manager destroys this object, and uses this memory slot for new objects.
imagine we have two classes:
class A:
def __init__(self):
self.b = B(self)
print('A: self: {0}, b:{1}'.format(hex(id(self)), hex(id(self.b))))
class B:
def __init__(self, a):
self.a = a
print('B: self: {0}, a: {1}'.format(hex(id(self)), hex(id(self.a))))
when you define an instance of class A:
my_var = A()
you will get this printed: (in your system, you will have different addresses)
B: self: 0x1fc1eae44e0, a: 0x1fc1eae4908
A: self: 0x1fc1eae4908, b:0x1fc1eae44e0
pay attention to the references. they are circular referenced.
NOTE: in order to see those references you have to disable the garbage collector otherwise it will delete them automatically.
gc.disable()
Currently reference count of my_var which is (0x1fc1eae4908) is 2. my_var and classB are referencing to this address. if we change the my_var
my_var= None
now my_var
is not pointing the same memory address. Now reference count of (0x1fc1eae4908) is 1 therefore this memory slot is not cleaned up.
now we will have Memory Leak which is when the memory is no longer needed is not cleaned up.
Garbage Collector will automatically identify the memory leak in circular references and clean them up. But if even one of the objects in the circular reference has a destructor (del()), Garbage Collector does not know the destruction order of the objects. So the object is marked as uncollectable and objects in the circular reference are not cleaned up which leads to memory leak.
weakref is used for caching purposes. I think python has very good documentation.
here is the reference for the weakref:
weakref documentation