Dav1d hat geschrieben:Alfons Mittelmeyer hat geschrieben:Jede Sprache verwaltet den Speicher automatisch. So werden lokale Variablen wieder gelöscht. Globale Variablen werden aber nicht gelöscht.
Du vermischt da einige Konzepte. In kompelierten Sprachen werden globale Variablen üblicherweise im `.data`-Segement abgelegt:
Du vermischt da einige Konzepte. Statische globale Variablen werden im '.data' - Segment abgelegt. Bei dynamisch allokiertem Speicher werden nur die Pointer also die Verweise auf den Speicher im '.data' Segment abgelegt. Und der Speicher wird dann aus dem Heap allokiert, etwa:
Code: Alles auswählen
# hier wird ein globaler Pointer myVar definiert, der im '.data' Segment als Verweis auf bisher nichts Brauchbares abgelegt wird.
# außerdem wird er als Pointer auf eine Klasse definiert, sodass er nur auf diese Klasse anwendbar ist
# (natürlich gibt es auch Möglichkeiten Pointer für beliebige Klassen zu verwenden mit Datentyp void und dann type casts)
MyClass * myVar = Null
# und hier findet dann die eigentliche Zuweisung statt, in der dann Speicher dynamisch allokiert wird
myVar = new MyClass(par1,par2,par3)
# und wenn der Speicher nicht freigegeben wird, bleibt dieser erhalten. Genauso ist es in Python. Zum Freigeben existiert der Befehl delete und in Python heißt er del
# Python hat allerdings eine Speicherverwaltung, die sich um Vieles kümmert, sodass man das del nicht explizit braucht, weil es in einigen Befehlen schon enthalten ist.
# wenn man in C++ nun das schreiben würde, wäre es verkehrt:
myVar = new MyClass(otherpar1,otherpar2,otherpar3)
# denn dadurch verursacht man ein Memory Leak, weil man jetzt neuen Speicher allokiert hat, ohne den alten freizugeben
# richtig daher:
delete myVar
myVar = new MyClass(otherpar1,otherpar2,otherpar3)
# In Python ist hier ein del völlig unnötig, wel das del bereits in der Zuweisung mit enthalten ist, genauso, wie etwa auch bei pop()
# Und wer hier del benutzt betreibt Mikroprogrammierung und hat von der Speicherverwaltung von Python nichts verstanden
Dav1d hat geschrieben:Also globale Variablen haben schonmal absolut nichts mit Speicherverwaltung zu tun (PS: ob die globale Variable mit static deklariert wurde oder nicht sieht man am `l` oder `g`).
Wie wir gesehen hatten, haben globale Pointer mit dynamisch allokiertem Speicher sehr wohl etwas mit Speicherverwaltung zu tun. Bei statischen Variablen bleibt allerdings der Speicher stets gleich und muss man sich nicht darum kümmern. Der Vorteil der Speicherverwaltung von Python ist, dass man sich normalerweise durch das in der Zuweisung und der pop-Funktion bereits enthaltene del, so ziemlich gar nicht um die Speicherverwaltung zu kümmern braucht. Stimmt natürlich nicht ganz, denn wer Daten in Listen und dergleichen speichert, da immer mehr hineinmüllt und sich nicht darum kümmert, dass etwas nur kurzzeitig gebraucht wurde, und glaubt, dass die Speicherverwaltung automatisch seinen Saustall aufräumt, der liegt verkehrt.
Dav1d hat geschrieben:Nun zur eigenltichen Speicherverwaltung, dem Heap, das "Gegenstück" zum Stack, welcher nicht automatisch wächst und Speicher nicht "automatisch" freigegeben werden wie beim Stack. Speicher der im Heap reserviert wird bleibt bestehen bis er wieder freigegeben wird. Man kann z.B. Speicher via `malloc` reservieren und wieder mit `free` freigeben, dann gibt es noch die Variante über einen Garbage Collector (von Jens angesprochen) Speicher zu reservieren, der GC kümmert sich darum dass Speicher wieder freigegeben wird sobald er nicht mehr benutzt wird (vereinfacht: er scannt den Speicherbereich nach Referenzen/Pointern, wenn er etwas findet dass in einen reservierten Bereich zeigt, wird der Speicher noch gebraucht und nicht freigegeben).
Daraus besonders dieser Teil:
der GC kümmert sich darum dass Speicher wieder freigegeben wird sobald er nicht mehr benutzt wird[/b] (vereinfacht: er scannt den Speicherbereich nach Referenzen/Pointern, wenn er etwas findet dass in einen reservierten Bereich zeigt, wird der Speicher noch gebraucht und nicht freigegeben).
Ob der Speicher noch benutzt werden soll, weiss der gc nicht. Er weiss nur ob der Referenzzähler Null ist oder nicht - bzw. ob die Referenz noch beinen reservierten Speicherbereich zeigt. Also, ob etwas noch gebraucht wird, weiß der gc nicht und wenn jemand Objekte, die er nicht mehr braucht, nicht aufräumen will sondern einfach weiter ansammelt, dann wird eben der Speicher vollgemüllt, bis Python bedendet wird oder bis es einen Crash gibt. Und bei lang laufenden Programmen mit großen Datenbeständen, kommt es eben dann zu Crashs.
Während lokale Variablen in Funktionen selber wieder beseitigt werden, werden globale Variablen nicht von selber aufgeräumt, sondern die Daten bleiben erhalten, bis man sie löscht. Warum man bei Einträgen in Listen und Directories dazu del nehmen darf, bei einzelnen Variablen dagegen nicht, bleibt ein Rätsel.
Dav1d hat geschrieben:Python benutzt einen solchen Garbage Collector (gibts übrigens auch für C/C++, z.B. libgc). Also alles was du tust ist im Grunde dem Garbage Collector die Arbeit zu erschweren und machst es teilweise sogar schlimmer (z.B. das copy). Es kann durchaus Situationen geben in denen `del` Sinn macht, allerdings für jemanden wie dich, der nicht wirklich versteht was los ist mit Memory Management sollte die Finger davon lassen.
Anscheinend bin ich der einzige hier der etwas vom Memory Management versteht. Und solche wie Du sollten da einfach besser still sein. Vielleicht viel Bücher gelesen, verstanden aber offentlich nichts.
Dav1d hat geschrieben:Fazit: Du verrennst dich da in Sinnlosem, wenn du wirklich ein low memory profile brauchst (also wirklich wirklich wirklich low), dann nimm nicht Python. Aber denke jetzt nicht, wusste ich doch gleich Python taugt nix, Garbage Collectoren sind scheiße. Python läuft ohne Probleme auf
Micro-Controllern und ein guter Garbage Collector kann durchaus mal schneller und effizienter sein als manuelles Memory Management von einem der keine Ahnung hat wies geht

.
PS: Wenn du versuchst Module zu entladen, das geht sowieso nicht wirklich:
http://bugs.python.org/issue9072.
Ich brauche kein low memory profile aber ein grow and grow and grow memory profile ebensowenig. Und Python ist optimal geeignet, hervorragend. Ein guter Garbage Collector kann keinen Saustall aufräumen, weil jemand den Speicher vollmüllt. Ein manuelles Memory Management brauche ich nicht. Denn ich habe die destroy() Funktion geschrieben, die den Speicher leer räumt. Und wer überhaupt keine Ahnung hat, bist Du. Sonst hättest Du gemerkt, dass ich darüber gar nicht mehr dikutieren brauche, weil ich die Funktion habe, die automatisch nach Ablaufen eines Scripts, den vom Script verwendeten Speicher wieder löscht. Und um Module ging es auch nicht, sondern um Scripts.