#!/usr/bin/env python # encoding: utf-8 """This file tests the memory purging of python by creating an instance of a class over and over again. It shows, that the instance is created at only one of two places over and over again, so the maximum additional memory consumed when replacing an instance is the size of the instance The reason seems to be that the instance is first created and then assigned to the variable. Only after that, the previous object gets deleted. This seems easy to understand, because this behaviour is necessary to allow for recursive functions where the new value of the variable depends on its previous value. """ # We want random, so that no optimizing of same objects can be done. from random import random # Now we create a memory hungry class. class MemoryHungry(object): """MemoryHungry is a class which just has many attributes which consume memory. For me one instance of MemoryHungry takes about 140Mib with number_of_atts=3,000,000 - bab. When I use a dict where I assign keys with random names to the value None (all the same object), this takes about 250MiB per instance. - bab """ def __init__(self, number_of_atts=3000000, mode="list"): if mode == "list": self.liste = [] #: list of random numbers elif mode == "dict": self.liste = {} #: dict with random numbers as keys # We add random numbers to teh list to make sure, that no memory usage can be optimized by grouping same objects or similar. for i in range(number_of_atts): self.blah = random() #: temporary random number # append self.blah to the list attribute of the class, so it consumes memory (as object of the list reassigning self.blah doesn't delete the value/instance of float): if mode == "list": self.liste.append(self.blah) if mode == "dict": self.liste[self.blah] = None # None is only one object, so what takes space here are the keys. # Also we create a class thirsty, which creates a float with the same content over and over again. class MemoryThirsty(object): """MemoryThirsty is a class which just has many attributes which consume memory. For me one instance of MemoryThirsty only takes about 70Mib with number_of_atts=3,000,000, which is half the amount taken by the same number of random numbers -bab. """ def __init__(self, number_of_atts=3000000): self.liste = [] #: List of random numbers # We add random numbers to the list to make sure, that no memory usage can be optimized by grouping same objects or similar. for i in range(number_of_atts): self.blah = 0.111111111111111111111111111111111 #: just a floating point number # append self.blah to the list attribute of the class, so it consumes memory (as object of the list reassigning self.blah doesn't delete the value/instance of float): self.liste.append(self.blah) ### Self-Test ### if __name__ == "__main__": # Create a MemoryHungry instance and give it to a variable over and over again. print "hunger" for i in range(10): # assign an instance of MemoryHungry to the variable hunger hunger = MemoryHungry(mode="dict") # And print the instance. print hunger, i pass print "hunger done" del hunger print "thirst" for i in range(10): # assign an instance of MemoryHungry to the variable hunger thirsty = MemoryThirsty() # And print the instance. print thirsty, i del thirsty # We're done. Say so. print "done"