Python-Anfragen nicht löschen Speicher beim Herunterladen mit Sitzungen

Ich habe eine Anwendung, wo ich Anfragen zum Herunterladen von .mp3 Dateien von einem Server.

Der Code sieht so aus:

self.client = requests.session(headers={'User-Agent': self.useragent}) def download(self, url, name): request = self.client.get(url) with open(name, "wb") as code: code.write(request.content) print "done" 

Das Problem ist, dass, wenn der Download beendet ist, python nicht den Speicher freigibt, also jedes Mal, wenn ich ein mp3 herunterladen, wird die Speicherauslastung der Anwendung durch die Größe des mp3 erhöht. Der Speicher wird nicht wieder gelöscht und führt zu meiner App mit viel Speicher.

Ich nehme an, das hat zu tun, wie ich die Datei speichern oder wie requests.session funktioniert.

Irgendwelche Vorschläge.

Bearbeiten: Hier ist der Code: https://github.com/Simon1988/VK-Downloader

Der relevante Teil ist in lib / vklib.py

2 Solutions collect form web for “Python-Anfragen nicht löschen Speicher beim Herunterladen mit Sitzungen”

Sie könnten versuchen, Streaming der Inhalt in Chunks:

 def download(self, url, name): request = self.client.get(url, stream=True) # `prefetch=False` for older # versions of requests with open(name, "wb") as code: for chunk in request.iter_content(1024): if not chunk: break code.write(chunk) 

Ich glaube nicht, dass es hier ein aktuelles Problem gibt, über Sie nicht zu verstehen, wie die Speicherzuteilung funktioniert.

Wenn Python mehr Speicher braucht, fragt es das Betriebssystem für mehr. Wenn es mit dieser Erinnerung fertig ist, gibt es es in der Regel nicht auf das Betriebssystem zurück; Stattdessen hält es für spätere Gegenstände an.

Also, wenn du den ersten 10MB mp3 öffnest, geht dein Speicher Gebrauch von, sagen wir, 3MB bis 13MB. Dann hast du das Gedächtnis frei, aber du bist immer noch bei 13MB. Dann öffnet man eine zweite 10MB mp3, aber es verwendet den gleichen Speicher, also bist du immer noch bei 13MB. Und so weiter.

In deinem Code schaffst du für jeden Download einen Thread. Wenn Sie 5 Threads zu einer Zeit haben, alle mit 10MB, offensichtlich das bedeutet, dass Sie mit 50MB. Und das 50MB wird nicht freigegeben. Aber wenn Sie darauf warten, dass sie fertig sind, dann machen Sie noch 5 Downloads, es wird wieder die gleiche 50MB wieder verwenden.

Da Ihr Code die Anzahl der Threads in keiner Weise beschränkt, gibt es nichts (kurz von CPU-Geschwindigkeit und Kontext-Switching-Kosten), um Sie davon abzuhalten, Hunderte von Threads zu starten, jede mit 10MB, was bedeutet, dass Gigabyte RAM. Aber nur Umschalten auf einen Thread-Pool, oder nicht lassen Sie den Benutzer treten mehr Downloads, wenn zu viele Gong auf, etc., wird das lösen.

Also, in der Regel ist das kein Problem. Aber wenn es so ist, gibt es zwei Möglichkeiten:

  1. Erstellen Sie einen untergeordneten Prozess (zB über das multiprocessing Modul), um die Speicher-Hogging-Arbeit zu machen. Auf irgendeinem modernen Betriebssystem, wenn ein Prozess weggeht, wird sein Gedächtnis zurückgefordert. Das Problem hier ist, dass die Zuweisung und Freigabe von 10MB immer und immer wieder wird Ihr System nach unten verlangsamen, nicht beschleunigen – und die Kosten für Prozess-Startup (vor allem auf Windows) wird es noch schlimmer machen. Also, Sie werden wahrscheinlich wollen eine viel größere Charge von Jobs zu spinnen, um ac Kind Prozess.

  2. Lasst das Ganze nicht sofort in Erinnerung; Verwenden Sie eine Streaming-API anstelle einer API mit einer ganzen Datei. Bei requests bedeutet dies, dass in der anfänglichen Anforderung die Einstellung stream=True und dann üblicherweise mit r.raw.read(8192) , r.iter_content() oder r.iter_lines() in einer Schleife statt auf r.content zugreifen.

  • Formular absenden und Datei mit Anfragen hochladen
  • Wie könnte ich Anfragen in asyncio verwenden?
  • Effiziente Lesung von Zeilen aus komprimierten, Chunked HTTP-Stream, wie sie ankommen
  • Problem beim Senden von POST-Anfragen unter Verwendung der Bibliotheksanforderungen
  • Richtiger Weg, um zu versuchen, außer mit Python-Anfragen-Modul?
  • Pythonwechsel Accept-Language mit Anfragen
  • Handhabung doppelter Schlüssel in HTTP-Post, um mehrere Werte zu spezifizieren
  • Anfragen - wie zum Streamen hochladen - Teildatei
  • Übersetzen von Multi-Byte-Zeichen in 7-Bit-ASCII in Python
  • Python-Anfrage für Google Drive
  • Anfragen können nicht mehrere Routen in derselben Flaschenanwendung aufrufen
  • Python ist die beste Programmiersprache der Welt.