Wie löst man einen Python-Speicherverlust bei Verwendung von urrlib2?

8

Ich versuche, ein einfaches Python-Skript für mein Mobiltelefon zu schreiben, um regelmäßig eine Webseite mit urrlib2 zu laden. Eigentlich interessiert mich die Serverantwort nicht, ich möchte nur einige Werte in der URL an PHP weitergeben. Das Problem ist, dass Python für S60 den alten 2.5.4 Python-Kern verwendet, der im Modul "urrlib2" ein Speicherleck zu haben scheint. Wie ich gelesen habe, scheint es auch in jeder Art von Netzwerkkommunikation solche Probleme zu geben. Dieser Fehler wurde vor ein paar Jahren hier gemeldet, und es wurden auch einige Problemumgehungen gepostet. Ich habe alles versucht, was ich auf dieser Seite finden konnte, und mit Hilfe von Google, aber mein Telefon hat immer noch nicht genug Speicher nach ~ 70 Seiten geladen. Seltsamerweise scheint der Garbege Collector auch keinen Unterschied zu machen, außer dass mein Skript viel langsamer wird. Es wird gesagt, dass der neuere (3.1) Kern dieses Problem löst, aber leider kann ich nicht ein Jahr (oder länger) auf den S60 Port warten.

Hier sehen Sie, wie mein Skript nach jedem kleinen Trick aussieht, den ich gefunden habe:

%Vor% Irgendwelche Vorschläge, wie man es für immer funktioniert, ohne den Fehler "Kann Speicher nicht zuordnen" zu bekommen? Danke für den Fortschritt, Prost, b_m

Aktualisierung: Ich habe es geschafft, 92 mal zu verbinden, bevor es nicht genug Speicher hatte, aber es ist immer noch nicht gut genug.

update2: Versucht die Socket-Methode wie zuvor vorgeschlagen, dies ist die zweitbeste (falsche) Lösung bisher:

%Vor% Ich habe die kleinen Tricks ausprobiert, auch von oben. Der Thread schließt sich nach ca. 50 Uploads (das Telefon hat 50MB Speicher übrig, offensichtlich hat die Python-Shell das nicht.)

UPDATE : Ich denke, ich komme der Lösung näher! Ich habe versucht, mehrere Daten zu senden, ohne den Socket zu schließen und wieder zu öffnen. Dies kann der Schlüssel sein, da diese Methode nur einen offenen Dateideskriptor zurücklässt. Das Problem ist:

%Vor% *: Fehlermeldung: 10053, Software hat Verbindungsabbruch verursacht

Warum kann ich nicht mehrere Nachrichten senden?

    
b_m 18.11.2010, 11:26
quelle

7 Antworten

0

Ich denke das ist wahrscheinlich dein Problem. Um diesen Thread zusammenzufassen, gibt es in der DNS-Suche von Pys60 einen Speicherleck, und Sie können umgehen, indem Sie die DNS-Suche außerhalb der inneren Schleife verschieben.

    
dll11 15.01.2011, 02:43
quelle
1

Mit dem von Ihrem Link vorgeschlagenen Testcode habe ich meine Python-Installation getestet und bestätigt, dass sie tatsächlich leckt. Aber, wenn, wie @ Russell vorgeschlagen hat, ich jedes urlopen in einen eigenen Prozess setze, sollte das OS die Speicherlecks bereinigen. In meinen Tests bleiben Speicher, nicht erreichbare Objekte und offene Dateien mehr oder weniger konstant. Ich habe den Code in zwei Dateien aufgeteilt:

connection.py

%Vor% %Vor%

Offensichtlich ist dies sequenziell, Sie werden also nur eine Verbindung gleichzeitig ausführen, was für Sie möglicherweise ein Problem darstellt. Wenn dies der Fall ist, müssen Sie eine blockierungsfreie Möglichkeit finden, mit den Prozessen, die Sie starten, zu kommunizieren, aber ich überlasse das als Übung für Sie.

BEARBEITEN : Wenn Sie Ihre Frage erneut lesen, scheint Ihnen die Serverantwort egal zu sein. In diesem Fall können Sie den Code für die Beize entfernen. Und natürlich werden Sie auch die print_unreachable_len() verwandten Bits in Ihrem endgültigen Code nicht haben.

    
Chinmay Kanchi 19.11.2010 16:06
quelle
1

Es gibt einen Referenzzyklus in urllib2, der in urllib2.py:1216 erstellt wurde. Das Problem ist im Gange und existiert seit 2009. Ссылка

    
imih 22.12.2016 10:15
quelle
0

Dies scheint wie eine (sehr!) hacky Workaround, aber ein wenig Googeln gefunden diesen Kommentar zu dem Problem:

Das Hinzufügen von f.read(1) stoppt das Lecken!

%Vor%

BEARBEITEN : Oh, ich sehe, du hast bereits f.read(1) ... Ich habe keine Ideen mehr: /

    
James 18.11.2010 11:37
quelle
0

Erwägen Sie, die Socket-API für die untergeordnete Ebene zu verwenden (howto ) anstelle von urllib2.

%Vor%

Wie man eine HTTP-Anfrage über Low-Level-Sockets ausführt und liest, ist ein wenig über den Rahmen der Frage hinaus (und könnte vielleicht eine gute Frage für Stackoverflow sein - ich habe gesucht, aber nicht gesehen), aber Ich hoffe, dies weist Sie in die Richtung einer Lösung, die Ihr Problem lösen kann!

bearbeiten Eine Antwort hier zur Verwendung von makefile könnte hilfreich sein: HTTP-Standardauthentifizierung mit Sockets in Python

    
Brian M. Hunt 19.11.2010 14:57
quelle
0

Das geht für mich nicht mit Python 2.6.1 auf einem Mac durch. Welche Version verwendest du?

Übrigens, Ihr Programm funktioniert nicht wegen ein paar Tippfehlern. Hier ist eine, die funktioniert:

%Vor%     
vy32 21.11.2010 13:07
quelle
0

Abhängig von der Plattform- und Python-Version gibt Python den Speicher möglicherweise nicht an OS zurück. Sehen Sie sich stackoverflow thread an. Das heißt, Python sollte nicht endlos Speicher verbrauchen. Nach dem verwendeten Code zu urteilen, scheint es ein Fehler in der Python-Laufzeit zu sein, es sei denn, , urllib / sockets benutzen globale Variablen, was ich nicht glaube - Schuld daran ist Python auf S60!

Haben Sie andere Quellen für Speicherlecks in Betracht gezogen? Endlose Log-Datei geöffnet, Array oder Smth immer größer? Wenn es wirklich ein Fehler in Sockets-Schnittstelle ist, dann ist Ihre einzige Option, den Subprozess Ansatz zu verwenden.

    
Konrads 22.11.2010 12:50
quelle