Hallo,
ich habe eine ganz einfache Frage:
Gibt es in Python einen clear-Befehl, wie in Matlab, der mir den Speicher löscht?
Gruß,
Michael
clear-Befehl wie in Matlab??
Wozu benötigst du so etwas?
Python hat einen Garbage Collector, der automatisch nicht benötigte Objekte aus dem Speichern entfernt -- und der tut seine Arbeit recht gut.
MfG EnTeQuAk
Python hat einen Garbage Collector, der automatisch nicht benötigte Objekte aus dem Speichern entfernt -- und der tut seine Arbeit recht gut.
MfG EnTeQuAk
Vielleicht willst du ja auf irgendeine krude Art und Weise dein Programm reinitialisieren?
Ich mach das so, dass ich einfach die __init__-Methode der entsprechenden Klasse nochmal aufrufe. Oder du erzeugst einfach eine neue Instanz.
Du brauchst dazu allerdings auch ne Klasse
Ich mach das so, dass ich einfach die __init__-Methode der entsprechenden Klasse nochmal aufrufe. Oder du erzeugst einfach eine neue Instanz.
Du brauchst dazu allerdings auch ne Klasse
Mich würde auch interessieren, was Du eigentlich vorhast? Vielleicht können wir Dir ja einen etwas pythonischeren Weg weisen?
Gruß,
Christian
Gruß,
Christian
...aber nicht gut genug. Pythons GC ist sehr primitiv. Er basiert auf einer Referenzzählung das die primitivste Implementierung eines GC`s darstellt und dessen nachteil eben ist, das es nicht mit zyklischen Referenzen umgehen kann!! Ruby dagegen verwendet einen richtigen Mark-and-Sweep-Algorithmus.EnTeQuAk hat geschrieben: Python hat einen Garbage Collector, der automatisch nicht benötigte Objekte aus dem Speichern entfernt -- und der tut seine Arbeit recht gut.
Im "normalen" Alltagsbetrieb hat man wohl kaum "selber" mit zyklischen Referenzen zu tun, aber sobald man einen Parser schreibt der Eingabe X nach Y überführt, wobei y ein Graph ist dessen Nodes kreisförmig aufeinander referenzieren, hat man ein großes Problem mit Speicherlecks! -- Umgehen kann man das ein wenig mit Hilfe von``weakref.proxy`` (Kreisförmige Referenzen werden über schwache Referenzen realisiert.)
IMO gehört das zu einer der größten schwächen von Python.
Interessierte sollte sich mal diesen link durchlesen, wobei ich die Meinung des Autors nicht vollständig teile, betreffend seiner Ansichten zu zyklischen Referenzen, das Mark-and-Sweep[1] "momentan" nicht implementierbar ist für Python ... Aber es liefert einen einblick wie Python da intern arbeitet. BTW: Ja der Artikel ist von 2000 aber IMO hat sich diesbezüglich bei Python nicht viel getan.
[1]:
Hmm! Hört sich genauso an wie der scheiß den GvR zum Thema tail call optimization gesagt hat Rubys Object-System kann man nicht gerade als primitiv bezeichnen (Der ist dem von Python in einigen dingen sogar überlegen) und da funktioniert der Mark-and-Sweep auch wunderbar (Ja, auch mit C extensions hat Ruby diesbezügliche keine Probleme).Unfortunately this approach cannot be used in the current version of Python. Because of the way extension modules work, Python can never fully determine the root set. If the root set cannot be determined accurately we risk freeing objects still referenced from somewhere. Even if extension modules were designed differently, the is no portable way of finding what objects are currently on the C stack...
@Zeddelsche:
Sorg dafür das kein Name mehr auf das betreffende Objekt referenziert und der GC springt da bei Gelegenheit[1] an und macht den Speicher frei. Wenn es um sehr viele Objekte geht die z.B. in einem Attribut X (z.B. eine Liste) einer Klasse gekapselt sind, und du ausschließen kannst das die darin befindlichen nirgendswo sonst an einem namen gebunden sind, genügt es einfach ``x=[]`` zu schreiben.
[1]: Gelegentlich deshalb, das es nicht vorhersehbar ist wann der GC den allokierten Speicherbereiche wider freigibt. Das kann der GC machen wennimmer er "Zeit" hat, aber muss es spätestens wenn der Speicher Aufgebraucht wird. -- Das einzige das IMO gewährleistet ist, das der Speicher von Funktions lokalen nach austritt freigegeben wird (Solange unter den lokalen keine Kreisförmige Referenz herrscht. Die werden wie gesagt nie freigegeben).
Python's GC kann auch Objekte mit zirkulären Referenzen freigeben. Ausnahme sind Kreise mit Objekten die eine `__del__()`-Methode besitzen, weil es da keinen Weg gibt zu entscheiden welches Objekt sicher als erstes entfernt werden kann.
Da man `__del__()` sowieso nicht vernünftig benutzen kann, weil so gut wie keine Garantien gemacht werden, wann und ob die Methode aufgerufen wird, sollten solche Kreise eher selten sein.
Da man `__del__()` sowieso nicht vernünftig benutzen kann, weil so gut wie keine Garantien gemacht werden, wann und ob die Methode aufgerufen wird, sollten solche Kreise eher selten sein.
-
- User
- Beiträge: 6
- Registriert: Freitag 28. September 2007, 07:10
Guten Morgen,
ich schreibe ein Programm in PythonWin und ändere beim Programmieren natürlich auch ständig den Code. estern ist es mir dann passiert, das ich eine Variable im Programm auskommentiert habe, da ich diese momentan nicht brauchte. Beim Programmablauf gab es dann aber Probleme, da die Variable noch im Speicher stand.
Matlab verhält sich hier ähnlich. Wenn man ein m-File ausführt werden alle Variablen in den Speicher geschrieben. Führt man ein anderes m-File aus, dann stehen die alten Variablen immer noch im Speicher. Um hier einen sauberen Schnitt zu machen, gibt es den Befehl clear(). Diesen fügt man einfach am Programmanfang ein und stellt damit sicher, dass sich nichts mehr im Speicher befindet.
So eine Funktion müsste es doch auch in Python geben, oder?
Gruß, Michael
ich schreibe ein Programm in PythonWin und ändere beim Programmieren natürlich auch ständig den Code. estern ist es mir dann passiert, das ich eine Variable im Programm auskommentiert habe, da ich diese momentan nicht brauchte. Beim Programmablauf gab es dann aber Probleme, da die Variable noch im Speicher stand.
Matlab verhält sich hier ähnlich. Wenn man ein m-File ausführt werden alle Variablen in den Speicher geschrieben. Führt man ein anderes m-File aus, dann stehen die alten Variablen immer noch im Speicher. Um hier einen sauberen Schnitt zu machen, gibt es den Befehl clear(). Diesen fügt man einfach am Programmanfang ein und stellt damit sicher, dass sich nichts mehr im Speicher befindet.
So eine Funktion müsste es doch auch in Python geben, oder?
Gruß, Michael
Das ist dann eher eine Frage der IDE oder Umgebung in der Du das laufen lässt und nicht von Python selbst. Bei IPython gibt es zum Beispiel in der Tat einen `clear`-Befehl für die Ein-/Ausgabe-History und einen `reset`-Befehl, der die benutzerdefinierten Namen entfernt.
Wenn Dich nur dieser eine Name stört, dann kannst Du ihn mit ``del name`` entfernen.
Grundsätzlich solltest Du aber Dein Arbeitsmodell überdenken und geänderten Code nicht in einer Umgebung ausführen, in der immer noch Reste von alten Läufen herumliegen könnten. Der interaktive Interpreter ist gut um mal etwas auszuprobieren, aber für Programmläufe sollte man schon eigene Skripte schreiben.
Wenn Dich nur dieser eine Name stört, dann kannst Du ihn mit ``del name`` entfernen.
Grundsätzlich solltest Du aber Dein Arbeitsmodell überdenken und geänderten Code nicht in einer Umgebung ausführen, in der immer noch Reste von alten Läufen herumliegen könnten. Der interaktive Interpreter ist gut um mal etwas auszuprobieren, aber für Programmläufe sollte man schon eigene Skripte schreiben.
- mkesper
- User
- Beiträge: 919
- Registriert: Montag 20. November 2006, 15:48
- Wohnort: formerly known as mkallas
- Kontaktdaten:
Hast du den Code während eines Debugs geändert und dann weiterlaufen lassen? Das würde das Verhalten erklären.Zeddelsche hat geschrieben:ich schreibe ein Programm in PythonWin und ändere beim Programmieren natürlich auch ständig den Code. estern ist es mir dann passiert, das ich eine Variable im Programm auskommentiert habe, da ich diese momentan nicht brauchte. Beim Programmablauf gab es dann aber Probleme, da die Variable noch im Speicher stand.
-
- User
- Beiträge: 6
- Registriert: Freitag 28. September 2007, 07:10
Nein, nicht während eines Debugs...
Also der Normalfall ist, dass Python-Programme mit einem "leeren Speicher" anfangen, da braucht man nicht extra einen Befehl für. Ich kenne PythonWin nicht, aber auch da sollte es möglich sein Programme richtig zu starten, und nicht in einem Namensraum auszuführen, der vorher schon einmal benutzt wurde.
Das ist also keine Python-Frage, sondern eine Deiner IDE.
Das ist also keine Python-Frage, sondern eine Deiner IDE.
- birkenfeld
- Python-Forum Veteran
- Beiträge: 1603
- Registriert: Montag 20. März 2006, 15:29
- Wohnort: Die aufstrebende Universitätsstadt bei München
Da hast du wohl was falsch verstanden. Das, was im Kontext von CPython als "GC" bezeichnet wird, ist der in IIRC 2.0 neue Cyclic Garbage Collector, der eben genau deswegen eingeführt wurde, weil zyklische Referenzen vorher Probleme machten.poker hat geschrieben:...aber nicht gut genug. Pythons GC ist sehr primitiv. Er basiert auf einer Referenzzählung das die primitivste Implementierung eines GC`s darstellt und dessen nachteil eben ist, das es nicht mit zyklischen Referenzen umgehen kann!!EnTeQuAk hat geschrieben: Python hat einen Garbage Collector, der automatisch nicht benötigte Objekte aus dem Speichern entfernt -- und der tut seine Arbeit recht gut.
-
- Python-Forum Veteran
- Beiträge: 16025
- Registriert: Freitag 20. Juni 2003, 16:30
- Kontaktdaten:
Deswegen steht der Artikel auf der Übersichtsseite unter Obsolete und der Patch ist für Python 1.5.2. Schade nur, dass das im Artikel nicht steht, dass die Informationen veraltet sind.birkenfeld hat geschrieben:Das, was im Kontext von CPython als "GC" bezeichnet wird, ist der in IIRC 2.0 neue Cyclic Garbage Collector, der eben genau deswegen eingeführt wurde, weil zyklische Referenzen vorher Probleme machten.
My god, it's full of CARs! | Leonidasvoice vs (former) Modvoice
Nein, nicht wenn er nur auf einer Referenzzählung im "Klassischen" (Erreichbarkeitsproblem im Graphen ignoriert wird.) Sinn basiert. Das liegt halt in der Natur der Sache. Es gibt aber Methoden um auch mit einem auf Referenzzählung basierenden GCs soweit aufzubohren das es Funktioniert, was IMO aber nirgendwo explizite erwähnt wurde.BlackJack hat geschrieben:Python's GC kann auch Objekte mit zirkulären Referenzen freigeben. Ausnahme sind Kreise mit Objekten die eine `__del__()`-Methode besitzen, weil es da keinen Weg gibt zu entscheiden welches Objekt sicher als erstes entfernt werden kann.
Ah, schön zu hören Das heißt das es nun Quasi zwei GCs in Python gibt oder der alte aufgebohrt wurde um das Erreichbarkeitsproblem im Graphen zu behandeln? Weil, der eigentliche GC basiert doch immer noch auf einer Referenzzählung, was man auch in den Python Extensions sehen kann (XINCREF, XDECREF).birkenfeld hat geschrieben: Da hast du wohl was falsch verstanden. Das, was im Kontext von CPython als "GC" bezeichnet wird, ist der in IIRC 2.0 neue Cyclic Garbage Collector, der eben genau deswegen eingeführt wurde, weil zyklische Referenzen vorher Probleme machten.
Hättest du vielleicht einen Link bezüglich des GCs von Python, wo die Funktionsweise genau spezifiziert ist?
@Leonidas: Jo, hätte ich vorher mal schauen müssen. Aber, hab den Link schon so langen in meinen Bookmarks, gehe auch in erster Linie davon aus, das Artikel die obsolet sind auch als solche gegenzeichnet werden im Artikel und habe es daher nicht gemacht.
EDIT:
@birkenfeld
Mal "eine" Frage, da du ja ein Dev im Core Team bist:
1. Warum hat man sich gegen einen Mark-and-Sweep entschieden bzw. nicht in betrachte gezogen? Die von mir im ersten Post Zitierte Begründung kann es doch irgendwie nicht sein.
2. Ist für Py3K eine Reformierung des Python GCs geplant? Eventuell Mark-and-Sweep
Ich würde sagen es gibt einen GC. Den Mechanismus mit den Referenzzählern sehe ich irgendwie nicht als GC an.
Ich glaube aber Du hast das Problem mit der `__del__()`-Methode nicht ganz erfasst. Innerhalb dieser Methode kann man ja auf die anderen Objekte im Kreis zugreifen. Ein sicheres Entfernen setzt also voraus, dass man entscheiden kann welches Objekt das *nicht* tut und damit als erstes entfernt werden kann. Von dem pathologischen Fall das es *alle* Objekte im Kreis tun und keines sicher als erstes entfernt werden kann, mal ganz abgesehen. Diese Entscheidung kann man bei so einer dynamischen Sprache wie Python einfach nicht automatisiert entscheiden.
Ich glaube aber Du hast das Problem mit der `__del__()`-Methode nicht ganz erfasst. Innerhalb dieser Methode kann man ja auf die anderen Objekte im Kreis zugreifen. Ein sicheres Entfernen setzt also voraus, dass man entscheiden kann welches Objekt das *nicht* tut und damit als erstes entfernt werden kann. Von dem pathologischen Fall das es *alle* Objekte im Kreis tun und keines sicher als erstes entfernt werden kann, mal ganz abgesehen. Diese Entscheidung kann man bei so einer dynamischen Sprache wie Python einfach nicht automatisiert entscheiden.
- birkenfeld
- Python-Forum Veteran
- Beiträge: 1603
- Registriert: Montag 20. März 2006, 15:29
- Wohnort: Die aufstrebende Universitätsstadt bei München
Ah, schön zu hören Das heißt das es nun Quasi zwei GCs in Python gibt oder der alte aufgebohrt wurde um das Erreichbarkeitsproblem im Graphen zu behandeln? Weil, der eigentliche GC basiert doch immer noch auf einer Referenzzählung, was man auch in den Python Extensions sehen kann (XINCREF, XDECREF).birkenfeld hat geschrieben: Da hast du wohl was falsch verstanden. Das, was im Kontext von CPython als "GC" bezeichnet wird, ist der in IIRC 2.0 neue Cyclic Garbage Collector, der eben genau deswegen eingeführt wurde, weil zyklische Referenzen vorher Probleme machten.
[/quote]
Ja, reference counting ist das hauptsächliche memory management. Der zyklische GC springt nur von Zeit zu Zeit an und kümmert sich um zirkuläre Referenzen.
Nein, auf die Schnelle nicht. Es müsste sich allerdings in den python-dev-Archiven einiges finden lassen aus der Zeit, in der der GC eingebaut wurde (um 2000 herum).Hättest du vielleicht einen Link bezüglich des GCs von Python, wo die Funktionsweise genau spezifiziert ist?
Da ich damals nicht dabei war, kann ich nur vermuten: Reference counting funktioniert soweit ja einwandfrei und schnell. Es ermöglicht deterministische Destruktion, wenn man alle Referenzen kennt. Das Hinzufügen des zyklischen GC war wahrscheinlich auch wesentlich einfacher, als das gesamte memory management auszutauschen.Mal "eine" Frage, da du ja ein Dev im Core Team bist:
1. Warum hat man sich gegen einen Mark-and-Sweep entschieden bzw. nicht in betrachte gezogen? Die von mir im ersten Post Zitierte Begründung kann es doch irgendwie nicht sein.
Nein, solange keiner wirkliche Gründe und einen Patch liefert.2. Ist für Py3K eine Reformierung des Python GCs geplant? Eventuell Mark-and-Sweep
@birkenfeld
Ich danke dir recht herzlich für diese aufschlussreichen Informationen, die meinen alten Wissenstand zu recht gerückt haben. Das Archeiv von 2000 werde ich bei Zeit durchforsten.
Aber die Dokumentation bezüglich ``__del__`` und des GCs kenne ich ja schon sehr lange ...
Nochmals vielen dank an euch beiden, das ihr mir meine Fragen beantwortet habt.
Ich danke dir recht herzlich für diese aufschlussreichen Informationen, die meinen alten Wissenstand zu recht gerückt haben. Das Archeiv von 2000 werde ich bei Zeit durchforsten.
Sonder was soll es sonst sein?BlackJack hat geschrieben:Den Mechanismus mit den Referenzzählern sehe ich irgendwie nicht als GC an.
Das kann natürlich sein.BlackJack hat geschrieben: Ich glaube aber Du hast das Problem mit der `__del__()`-Methode nicht ganz erfasst.
Aber die Dokumentation bezüglich ``__del__`` und des GCs kenne ich ja schon sehr lange ...
... aber ich hab das nicht für einen Grund angesehen der es unmöglich macht einen Mark-and-Sweep zu implementieren. Aber deine Ausführung klingt logisch, und das könnte IMO ein grund sein weshalb es in Ruby geht, da es da sowas nicht wie eine ``__del__`` Methode gibt (Nicht das ich wüsste).BlackJack hat geschrieben: Innerhalb dieser Methode kann man ja auf die anderen Objekte im Kreis zugreifen. Ein sicheres Entfernen setzt also voraus, dass man entscheiden kann welches Objekt das *nicht* tut und damit als erstes entfernt werden kann. Von dem pathologischen Fall das es *alle* Objekte im Kreis tun und keines sicher als erstes entfernt werden kann, mal ganz abgesehen. Diese Entscheidung kann man bei so einer dynamischen Sprache wie Python einfach nicht automatisiert entscheiden.
Nochmals vielen dank an euch beiden, das ihr mir meine Fragen beantwortet habt.