2012-05-24 8 views
5

feuerte ich meine JRuby irb Konsole und tippte:JRuby - Wie starte ich den Garbage Collector?

irb(main):037:0* GC.enable 
(irb):37 warning: GC.enable does nothing on JRuby 
=> true 
irb(main):038:0> GC.start 
=> nil 
irb(main):039:0> 

Wie kann ich manuell aktivieren oder die JVM Müll während eines Programms starten?

Ich frage, weil ich ein Programm habe, das etwa 500 MByte Testdaten generieren und in MySQL speichern soll. Das Programm verwendet ungefähr 5 Ebenen verschachtelter Schleifen und stürzt mit einer JVM-Speicher-Heap-Ausnahme ab, nachdem ungefähr 100 MB Testdaten generiert wurden, da kein Heap-Speicher mehr vorhanden ist. Ich möchte den Garbage Collector nach jedem Durchlauf der äußeren Schleife laufen lassen, damit alle in den inneren Schleifen erstellten verwaisten Objekte aufgeräumt werden können.

+1

Es ist unwahrscheinlich, dass es hilft, denn wenn die JVM nicht mehr genügend Arbeitsspeicher hat, wird der GC ausgeführt, bevor er aufgibt. Möglicherweise müssen Sie sicherstellen, dass Sie Referenzen nicht länger halten, als sie benötigt werden, und/oder die Heap-Größe erhöhen. – theglauber

Antwort

10

Die genaue Antwort auf Ihre Frage wäre:

require 'java' 

java_import 'java.lang.System' 

# ... 

System.gc() 

aber wenn man bedenkt, obwohl die JVM in der Regel nicht die GC laufen, kann es oder kann es nicht tun - sehr abhängig von der JVM Implementierung. Es kann auch ziemlich stark auf Leistung sein.

Eine bessere Antwort ist natürlich sicherzustellen, dass am Ende der Nested-Schleife keine Referenz auf die von Ihnen generierten Testdaten gehalten wird, damit sie später von der GC zurückgewonnen werden können. Beispiel:

class Foo; end 

sleep(5) 

ary = [] 
100_000.times { 100_000.times{ ary << Foo.new }; puts 'Done'; ary = [] } 

Wenn Sie dies mit jruby -J-verbose:gc foo.rb ausführen, sollten Sie die GC regelmäßig die Objekte behauptet, sehen; das ist auch ziemlich klar mit JVisualVM (das sleep in dem Beispiel soll etwas Zeit geben, um sich mit dem Jruby-Prozess in JVisualVM zu verbinden).

Schließlich können Sie den Heapspeicher erhöhen, indem Sie das folgende Flag hinzufügen: -J-Xmx256m; Weitere Informationen finden Sie unter the JRuby wiki.

Bearbeiten: Zufälligerweise ist hier a mindmap on GC tuning vor kurzem präsentiert von Mario Camou in Madrid DevOps re-posted von Nick Sieger.

+0

Merci Beaucoup Sébastien. Ihre Vorschläge waren sehr hilfreich und haben uns geholfen, mehr Fragen zu stellen (und zu beantworten), als wir dachten. –

+1

Der Evernote-Link scheint tot zu sein ... –

+0

Thans für die Antwort. ein weiteres Beispiel: https://gist.github.com/Shobhit1/f4ec5c9f1f47f3b8e70bb7d27a78fba9 – shobhit1

-1

Dies ist nicht möglich, da Gc automatisch von JVM ausgeführt wird. Stellen Sie sicher, dass Sie Objekte nur dann erstellen, wenn sie benötigt werden. Vermeiden Sie das Erstellen von Objekten auf Klassenebene und versuchen Sie herauszufinden, welches der Objekte mehr Arbeitsspeicher beansprucht und erstellen Sie es nur, wenn es erforderlich ist.

+0

Das ist nicht wahr. Sie haben einen guten Rat, aber es ist möglich, GC manuell auszuführen. – Overbryd