Wenn ich dies starte und dann den Speicherverbrauch meines Ruby-Prozesses im OSX Activity Monitor beobachte, erhöht sich der Speicher auf ca. 3 MB / s.
Wenn ich die Transaktion entferne, halbiert sich der Speicherverbrauch, aber der Speicherbedarf steigt weiter an. Ich habe ein Problem mit meiner Produktions-App, bei der Heroku den Prozess aufgrund seines Speicherverbrauchs beendet.
Gibt es eine Möglichkeit, das Folgende zu tun, und zwar so, dass das Gedächtnis nicht erhöht wird? Wenn ich die .save
-Zeile auskommentiere, ist das okay, aber das ist natürlich keine Lösung.
Ich verwende dies mit delayed_job
.
Die Zeile a = nil
ist unnötig und Sie können diese entfernen.
Sie erstellen bei jeder Schleife eine Menge Objekte - zwei Strings, zwei Hashes und ein Activity-Objekt. Ich bin also nicht überrascht, dass Sie eine hohe Speicherauslastung haben, besonders, wenn Sie 10 Millionen Male loopen! Es scheint keine speichereffizientere Möglichkeit zu geben, diesen Code zu schreiben.
Die einzige Möglichkeit, die Speichernutzung zu reduzieren, besteht darin, den Garbage Collector manuell nach jeder x Anzahl von Iterationen zu starten. Die Wahrscheinlichkeit ist groß, dass Rubys GC nicht aggressiv genug ist. Sie möchten jedoch nicht jede Iteration aufrufen, da dies Ihren Code radikal verlangsamen wird. Vielleicht könntest du alle 100 Iterationen als Ausgangspunkt nehmen und von dort aus gehen. Sie müssen profilieren und testen, was am effektivsten ist.
Die Dokumentation für den GC ist hier .
Ich weiß, dass dies ein altes Problem ist, aber ich muss einen anderen radikalen Ansatz vorschlagen:
%Vor%Der Punkt ist, dass, wenn die Einfügung so einfach ist und Sie bereits eine Validierung von ActiveModel überspringen, es keinen Grund gibt, ein ActiveRecord-Objekt überhaupt zu instanziieren. Normalerweise würde es nicht weh tun, aber da es dich in diesem Fall verletzt, denke ich, dass du auf diese Weise viel weniger Speicher verwenden wirst.
Tags und Links ruby ruby-on-rails memory-management