2016-06-22 13 views
1

Unten Code hat Speicherverlust. Es läuft unter Ruby 2.1.1. Ich kann das tatsächliche Leck nicht finden.Ruby-Code-Speicherverlust in der Schleife

q = Queue.new("test") 
while true do 
    m = q.dequeue 
    body = JSON.parse(m.body) 
    user_id = body["Records"][0] 
    user = V2::User.find(user_id) 
    post = V2::Post.find(post_id) 
end 

Nach wenigen Stunden Lauf Ich habe GC.start aber es ist nicht das Problem zu lösen

q = Queue.new("test") 
while true do 
    m = q.dequeue 
    body = JSON.parse(m.body) 
    user_id = body["Records"][0] 
    user = V2::User.find(user_id) 
    post = V2::Post.find(post_id) 
    GC.start 
end 

Ich weiß nicht, wie die tatsächliche Speicherverlust zu finden.

+3

Wie wird 'Warteschlange' definiert? Wie sieht 'Queue # dequeue' aus? (Ich habe bemerkt, dass' dequeue' nicht für die 'Queue' definiert ist, die mit Ruby geliefert wird). Wer reiht Objekte in die Warteschlange ein? Wie viele Objekte sind im Durchschnitt in der Warteschlange? – spickermann

+0

Wurde Ihre Frage beantwortet? – Dbz

Antwort

1

Versuchen Sie, die Leitungen von unten nach oben zu entfernen und zu überprüfen, ob das Speicherleck bestehen bleibt. Es ist möglich, dass das Speicherleck von der Find-Methode oder möglicherweise der JSON.parse (extrem unwahrscheinlich) oder der benutzerdefinierten Queue-Datenstruktur stammt. Wenn das Speicherleck nach dem Entfernen aller Zeilen immer noch vorhanden ist, kommt es wahrscheinlich von dem Arbeiter selbst und/oder dem Programm, das die Arbeiter ausführt.

q = Queue.new("test") 
while true do 
    m = q.dequeue # Finally remove this and stub the while true with a sleep or something 
    body = JSON.parse(m.body) # Then remove these two lines 
    user_id = body["Records"][0] 
    user = V2::User.find(user_id) # Remove the bottom two lines first 
    post = V2::Post.find(post_id) 
end 
+0

Auf den ersten Blick dachte ich das Gleiche. Diese Schleife würde sicherlich zu einer hohen CPU-Auslastung führen, aber warum sollte sie zu einer hohen Speichernutzung führen? – spickermann

+0

@Dbz Eigentlich ist es ein Arbeiter. Es wird für jede Sekunde laufen. Es wird Liston die Warteschlange. Wenn eine Nachricht in die Warteschlange geschoben wird, nimmt sie die Nachricht aus der Warteschlange und führt den Job aus. – SaravanaKumAr

+0

Yup. Ihr habt definitiv Recht. Ich habe meine Antwort mit Debugging-Tipps aktualisiert. Stellen Sie sicher, dass Sie die Ergebnisse veröffentlichen, nachdem Sie dies versucht haben. – Dbz

0

Ich wette, das Problem ist mit eingeführten lokalen Variablen (sic!). Befreien Sie sich von user_id und post_id und es wird wahrscheinlich aufhören undicht:

# user_id = body["Records"][0] 
# user = V2::User.find(user_id) 
user = V2::User.find(body["Records"][0]) # sic! 

Der Grund dafür ist, wie Ruby-stores objects in RValues.

+0

Nach jedem GC.start wird der lokale Variablenspeicher freigelassen? – SaravanaKumAr

+0

Nein, nicht richtig. Bitte folgen Sie der Antwort, die ich verlinkt habe. – mudasobwa

+0

Zum Beispiel bin ich eine Schleife 1000 Mal. Innerhalb dieser Schleife wird jedesmal user_id = some_value zugewiesen. Auch jede Schleife läuft GC.start. In diesem Fall, wenn der Speicher freigegeben wird ?. Was ist deine Meinung dazu? während ich <1000 i ++ user_id = ich GC.start Ende – SaravanaKumAr

Verwandte Themen