ruk·si

🐍 Python
Memory

Updated at 2017-01-02 23:30

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