2012-05-24 16 views
5

Ho sparato il mio console irb JRuby e digitato:JRuby - Come avviare il 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> 

Come posso abilitare o avviare la spazzatura JVM durante un programma manualmente?

Chiedo perché ho un programma che deve generare circa 500 MB di dati di test e salvarlo in MySQL. Il programma utilizza circa 5 livelli di cicli nidificati e si blocca con un'eccezione di memoria JVM dopo aver generato circa 100 MB di dati di test perché non c'è più memoria heap. Vorrei lasciare che il garbage collector funzioni dopo ogni ciclo del ciclo esterno in modo che tutti gli oggetti orfani creati nei loop interni possano essere ripuliti.

+1

È improbabile che aiuti, perché se la JVM ha esaurito la memoria, eseguirà il GC prima di arrendersi. Potrebbe essere necessario assicurarsi di non conservare i riferimenti più a lungo del necessario e/o aumentare le dimensioni dell'heap. – theglauber

risposta

10

La risposta esatta alla tua domanda potrebbe essere:

require 'java' 

java_import 'java.lang.System' 

# ... 

System.gc() 

però, tenendo conto anche se la JVM di solito non eseguire il GC, si può o non può farlo - dipende molto dalla JVM implementazione. Può anche essere piuttosto un successo sulle prestazioni.

Una risposta migliore è ovviamente quella di garantire che alla fine del ciclo annidato non venga tenuto alcun riferimento sui dati di test che si stanno generando, in modo che possano essere successivamente recuperati dal GC in seguito. Esempio:

class Foo; end 

sleep(5) 

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

Se si esegue questo con jruby -J-verbose:gc foo.rb, si dovrebbe vedere la GC sostenendo regolarmente gli oggetti; questo è anche abbastanza chiaro usando JVisualVM (lo sleep nell'esempio è di dare un po 'di tempo per connettersi al processo Jruby in JVisualVM).

Infine, è possibile aumentare la memoria heap aggiungendo il seguente flag: -J-Xmx256m; vedi the JRuby wiki per maggiori dettagli.

Edit: Per coincidenza, qui è a mindmap on GC tuning recentemente presentato da Mario Camou a DevOps Madrid ri-postato da Nick Sieger.

+0

Merci beaucoup Sébastien. I tuoi suggerimenti sono stati molto utili e ci hanno aiutato a chiedere (ea rispondere) più domande di quanto pensassimo. –

+1

Il collegamento evernote sembra morto ... –

+0

Thans per la risposta. un altro esempio: https://gist.github.com/Shobhit1/f4ec5c9f1f47f3b8e70bb7d27a78fba9 – shobhit1

-1

Non è possibile perché Gc verrà eseguito automaticamente da JVM. Assicurati di creare oggetti solo quando è richiesto. Evita di creare oggetti di livello di classe e prova a scoprire quale degli oggetti sta prendendo più memoria e lo crea solo quando è necessario.

+0

Non è vero. Hai un buon consiglio, ma è possibile eseguire manualmente GC. – Overbryd