Python Speicherverwaltung

Ich habe einen kleinen Test gemacht, um zu schauen, wie die Speicherverwaltung von Python funktioniert.

Dafür habe ich eine Klasse erzeugt, die eine extrem lange Liste als Attribut hatte, so dass viel Ram verbraucht wurde.

Dann habe ich mehrfach eine Instanz dieser Klasse der gleichen Variable zugewiesen.

Das Ergebnis war, dass höchstens der doppelte Speicherbedarf einer einzelnen Instanz verbraucht wurde.

Außerdem habe ich herausgefunden, dass ein dict mit 3 Millionen unterschiedlichen Schlüsseln, die auf das gleiche Objekt zeigen (None), etwa doppelt so viel Ram braucht wie eine Liste, die diese Schlüssel als Werte hat.

Das Skript zum Testen habe ich angehängt und poste es auch nochmal hier.

Viel Spaß beim selbst mit Python spielen :)

#!/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"
AnhangGröße
python_memory_cleaning_test.py.txt3.56 KB
Inhalt abgleichen
Willkommen im Weltenwald!
((λ()'Dr.ArneBab))



Beliebte Inhalte

sn.1w6.org news