🐍 Python - Memory
Python keeps objects in memory as long as they are referred. When nothing points to an object, it is instantly cleaned by the garbage collector.
You can use weak references to allow garbage collection. This might be useful e.g. in caching or keeping count of instances of a class. You can use weakref.finalize
, weakref.WeakValueDictionary
, weakref.WeakKeyDictionary
and weakref.WeakSet
.
import weakref
n1 = {1, 2}
n2 = n1
def bye() -> None:
print('Bye Bye')
finalizer = weakref.finalize(n1, bye)
assert finalizer.alive
assert finalizer.peek()[0] == {1, 2}
del n1
assert finalizer.alive
assert finalizer.peek()[0] == {1, 2}
n2 = {5, 6}
# => Bye Bye
assert not finalizer.alive
assert finalizer.peek() is None
Use __slots__
to reduce memory footprint of objects. Object attributes are stored in a dictionary by default and as dicts have large memory overhead, it certainly makes sense to use tuples to store the attributes if you are creating million of instances. Note that __slots__
is not inherited so you need to redefine it for subclasses. If you are using weak references, also include __weakref__
in the slots.
class MemoryEfficientVector:
__slots__ = ('__x', '__y') # class cant have any other attrs
def __init__(self, x, y):
self.__x = x
self.__y = y
@property
def x(self):
return self.__x
@property
def y(self):
return self.__y
v1 = MemoryEfficientVector(1, 2)
Source
- Fluent Python, Luciano Ramalho