Seite 1 von 1

Speicherverwaltung

Verfasst: Montag 29. Mai 2006, 20:39
von Lambert
Hallo zusammen,

Ich arbeite in der Robotersimulation. Python ist dabei als Schnittstelle implementiert. Ich muss nun berechnungen durchführen lassen. Leider können diese Berechnungen schnell in die Tausende bzw. Zehntausende gehen.
Hier meine Frage: Gibt es von Python eine Grenze. Sowas wie eine maximal Anzahl an berechnungen? Wenn nicht dann liegt es an meinem Simulationsprogramm. Denn das bricht nach 10.000 Schritten ab. Gibt es eine möglichkeit den Speicher wieder frei zu machen. Die Liste die ich für meine Variablen benutze überschreibe ich bei jedem Schleifendurchgang. Es ist so ändlich wie:

Code: Alles auswählen

for line in datei:
    t = []
    t.append(string.splite(line))
    #berechnung mit t
Nachdem diese Schleife einige Tausendmal durchlaufen wurde bricht das Program ab.

Vielleicht weiß von euch ja jemand wie ich den Speicher wieder auf Null setze.

Gruß
Lambert

Edit (Leonidas): Code in Python-Tags gesetzt.

Verfasst: Montag 29. Mai 2006, 20:44
von murph
mit flush().
das aber auch nur, wenn er gerade zeit hat, ist also nicht leicht!
der flush() arbeitet nämlich nur, wenn grad nix zu tun ist.
sonst auch möglich, aber ungerne gesehen: del
sprich:

Code: Alles auswählen


for line in datei:
    t = []
    t.append(string.splite(line))
    #berechnung mit t
    #schreibe in datei(bin zu faul dazu^^)
    del t

Verfasst: Montag 29. Mai 2006, 20:46
von Lambert
Und das ändert was. In dem ich immer wieder t = [] aufrufe überschreibe ich doch. Bedeutet das nicht auch das ich lösche?

Verfasst: Montag 29. Mai 2006, 20:49
von murph
an sich schon, aber der rechner ist zu langsam; und bevor er das löschen wird, rechnet er nunmal lieber weiter, um den user nicht durch zeitverzögerung zu ärgern.
alternative wäre ein anderer treiber, der die zeit nicht so genau nimmt, dafür aber das flushen/deleten. Aber das wäre bei einem projekt wie bei dir auch nicht wünschenswert, wenn man nicht auf den zusammenhang messergebnis-zeit verzichten will...

Verfasst: Montag 29. Mai 2006, 20:54
von Lambert
Vielen Dank. Die Zeit spielt allerdings bei meinem Projekt mal keine Rolle. Die Berechnung geht so schnell das der Roboter in 1000 Jahren nicht daran kommen würde. Also kann ich mir mit der Simulation auch Zeit lassen. Mich würde es nicht mal stören wenn der Computer einen Tag lang rechnet. Nur abbrechen darf er nicht.

Verfasst: Montag 29. Mai 2006, 20:58
von murph
das ganze kannst du ja auch mit time.sleep abändern, damit er sich die zeit nimmt, das alles auszurechnen und zu löschen, dann würde auch die ram nicht volllaufen

Re: Speicherverwaltung

Verfasst: Montag 29. Mai 2006, 21:28
von BlackJack
Lambert hat geschrieben:Hallo zusammen,

Ich arbeite in der Robotersimulation. Python ist dabei als Schnittstelle implementiert. Ich muss nun berechnungen durchführen lassen. Leider können diese Berechnungen schnell in die Tausende bzw. Zehntausende gehen.
Hier meine Frage: Gibt es von Python eine Grenze. Sowas wie eine maximal Anzahl an berechnungen? Wenn nicht dann liegt es an meinem Simulationsprogramm. Denn das bricht nach 10.000 Schritten ab.
Nein so eine Grenze gibt's in Python nicht. Höchstens vom Betriebsystem wenn zu viel Speicher angefordert wird. Diese Grenze hast Du aber in jeder Programmiersprache.
Gibt es eine möglichkeit den Speicher wieder frei zu machen. Die Liste die ich für meine Variablen benutze überschreibe ich bei jedem Schleifendurchgang. Es ist so ändlich wie:

Code: Alles auswählen

for line in datei:
    t = []
    t.append(string.splite(line))
    #berechnung mit t
Nachdem diese Schleife einige Tausendmal durchlaufen wurde bricht das Program ab.
Was heisst es bricht ab? Mit welcher Fehlermeldung? Und wieso glaubst Du, dass es am Speicher liegt?

Übrigens brauchst Du nicht immer eine neue leere Liste anlegen nur um mit `append()` eine Liste als Element hinzuzufügen und die Funktionen aus dem `string` Modul, die auch als Methoden auf Zeichenketten existieren sollte man nicht mehr benutzen:

Code: Alles auswählen

for line in datei:
    t = line.split()
    # Berechnungen mit `t`.

Verfasst: Montag 29. Mai 2006, 22:07
von Joghurt
Was bitte schön soll flush mit dem Garbage Collector zu tun haben?

Den Code, den Lambert zuerst gepostet hat, sollte keinen Speicherüberlauf produzieren.

Verfasst: Dienstag 30. Mai 2006, 06:59
von Lambert
Es ist so das Python eingebettet ist in mein Simulationsprogramm. Es kommt garkeine Fehlermeldung. Ich nehme deshalb an das die Berechnung nicht von Python oder dem Betriebsystem abgebrochen wird, sondern vom Simulationsprogramm. Es könnte sein das es da einen Schutz vor Endlosschleifen gibt. Ich probiere unterschiedlich Viele Berechnungen. Und bei einer Anzahl von unter 10.000 läuft das Program einwandfrei durch. Aber alles darüber oder +-200 wird abgebrochen. Deswegen denke ich es liegt am Speicher.

Mit del funktioniert es leider auch nicht. Aber danke für den Tip mit line.split().

Gibt es vielleicht irgendeine Methode mit der ich den Speicher wärend der Ausführung überwachen kann?


Gruß
Lambert

Verfasst: Dienstag 30. Mai 2006, 08:05
von Rebecca
Was fuer ein Betriebssystem?

Unter Linux gibt's zum Beispiel das Kommando top. Ich habe (unter Linux) mal was ausprobiert:

Code: Alles auswählen

>>> a = []
>>> while True:
...     a.append("bla")
... 
Traceback (most recent call last):
  File "<stdin>", line 2, in ?
MemoryError
(Zugegeben, nicht die schnellste Methode, den Speicher vollzukriegen. Hat mehrere Minuten gedauert...) Man kann in mit top wunderbar sehen, was passiert.

Aber wie Joghurt schon sagte, Lamberts Code sollte keine Speicherprobleme verursachen. Trotzdem, Lambert, du koenntest ja mal versuchen, einen MemoryError abzufangen.

Vielleicht macht dieses Simulationsprogramm auch merkwuerdige Sachen? Du koenntest auch mal deinen Code (oder einen aehnlichen) in reinem Python ausfuehren, ohne die Anbindung an die Simulation. Vielleicht siehst du dann auch eine Fehlermeldung?

EDIT: Ueberhaupt, wenn du keine Fehlermeldungen abgezeigt bekommst, koenntest du dein gesamtes Programm in einen try-Block einschliessen und dir dann die eventuellen Fehlermeldungen ausgeben lassen, in eine Datei zum Beispiel. Da waere dann das traceback-Modul hilfreich.

Verfasst: Dienstag 30. Mai 2006, 10:09
von Joghurt
Falls du unter Linux arbeitest, und den Quellcode des Simulationsprogrammes hast, kann ich valgrind empfehlen. Das Simulationsprogramm läuft dann in einer virtuellen Maschine, die nach Speicherlecks sucht.

http://www.valgrind.org

Verfasst: Dienstag 30. Mai 2006, 10:15
von Lambert
Ich fürchte ich arbeite mit Windows. Es bleibt mir auch nichts anderes übrig, da die Simulationssoftware nur auf Windows läuft.
Ich hab jetzt alles durchprobiert. Timer.sleep, flush und del. Hilft alles nichts. Ich kann mir nicht mal eine exception ausgeben lassen. Das Python-Skript wird einfach beendet.
Vermutlich muss ich mich da doch ehr an die Firma von dem Simulationstool wenden. Es sei den es hat noch wer einen ganz heißen Tip. Oder ein Überwachungsprogramm für Windows.

Gruß
Franz

Verfasst: Dienstag 30. Mai 2006, 10:32
von gerold
Lambert hat geschrieben:Oder ein Überwachungsprogramm für Windows.
Hallo Franz!

Strg-Alt-Entf --> Task Manager

Mit dem kannst du -- allgemein -- den Speicherverbrauch und die Prozessorauslastung anzeigen lassen.

Unter "Windows 2000 Pro" oder -Server kannst du dir den "Systemmonitor" installieren. Der ist bei Windows mit dabei. Die Home-Versionen von Windows kenne ich nicht. Da ist er evt. nicht dabei. Damit kannst du ebenfalls -- unter anderem -- den Speicher überwachen.

Lässt sich der Fehler auf einem anderen Computer reproduzieren? Wenn ja, dann liegt es wahrscheinlich nicht an einem fehlerhaften RAM-Baustein.

Du könntest ja auch in deinen Code einige "print"-Anweisungen einbauen.
Damit bekommst du raus wo dein Programm abbricht.

Bricht das Programm, bei gleichem Input, immer an der exakt gleichen Stelle ab, oder variiert es?

Bricht das Programm schneller ab, wenn du den Speicher vorher durch viele offene Programme (Word, Excel, Access, ...) vollmüllst? Wenn Ja, dann verbrauchst du zu viel Speicher. Wir wissen ja nicht, was du so alles in deiner Schleife machst.

Du kannst deinen Speicherverbrauch drastisch reduzieren, wenn du nicht alles in den Speicher lädst, sondern mit den Daten in den Dateien direkt arbeitest. Eventuell kannst du dafür auch das Modul "shelve" verwenden. Das wirkt Wunder, da es die Daten im Dateisystem hält. Trotzem lässt sich damit wie mit einem Dictionary arbeiten.

Vielleicht bekommst du eine bessere Fehlermeldung, wenn du deine Schleife in "try" und "except" einhüllst.
http://www.python-forum.de/post-8616.html#8616
Allerdings würde ich die anderen "try" und "exept" aus der Schleife entfernen, damit keine andere Fehlerbehandlung dazwischenfunken kann.

Mehr fällt mir im Moment nicht ein.

mfg
Gerold
:-)

Verfasst: Dienstag 30. Mai 2006, 10:35
von gerold
Doch, etwas fällt mir noch ein.

Vielleicht ist in den Dateien, die du so durchläufst etwas drinnen, was das Programm zum Abstürzen bringt.

Öffne zum Test die Dateien mal nicht mit "r", sondern mit "rb".
Z.B.:

Code: Alles auswählen

f = file("dateiname", "rb")
for line in f:
    <tu etwas>
f.close()
Wenn das nicht geht, dann könnte eventuell noch das U helfen. Je nachdem, welcher Text in den Dateien steht.
Z.B.:

Code: Alles auswählen

f = file("dateiname", "rU")
for line in f:
    <tu etwas>
f.close()
mfg
Gerold
:-)

Verfasst: Dienstag 30. Mai 2006, 10:46
von Masaru
Wenn's immer noch nicht klappt, beschreib mal ansonsten näher das was du tust. Wie Gerold schon meinte fehlen ein paar mehr Infos um detailiert auf dein Problem einzugehen.

Was mir noch einfällt bezüglich der Exceptions:
Ich würde einmal versuchen absichtlich eine Exception zu raisen, um zu prüfen, ob nicht die Simulatiosnsoftware irgendwie diese selber abfängt und nicht nach draussen durchlässt (sondern vielleicht in eine Log-File schreibt, oder gar gänzlich ignoriert).

Code: Alles auswählen

#code ...
raise NotImplementedError("Test")
#code ...

Verfasst: Freitag 2. Juni 2006, 12:39
von Lambert
Danke euch allen. Aber letzendlich war es doch ein Fehler der Simulation. Die hat scheinbar eine Beschränkung eingebaut. Es können insgesamt nur so und soviele Befehle ausgeführt werden. Wahrscheindlich um Endlosschleifen zu vermeiden. Aber es gab eine "Reset"-Methode. Mit der konnte ich den Counter wieder auf Null setzen. Aber nochmal danke. Eure Tipps haben mir inzwischen bei anderen Problemen geholfen.

Schöne Grüße
Lambert