2013-06-26 7 views
5

Ho un'applicazione JRuby on Rails in esecuzione in Tomcat (Warble). Utilizza un bridge Java per connettersi a un server delle applicazioni Progress (OpenEdge) ... Quando controllo la memoria, continua a salire.Perché la memoria non viene mai rilasciata nella mia applicazione Tomcat JRuby?

  • Tomcat 7.0
  • JRuby 1.6.7.2 (Ruby-1.9.2-P312)
  • JVM 1.7.0.25
  • Rails 3.2.7
  • JRuby-rack 1.1.7
  • Luì 1.3.6

Qual è il modo migliore per arrivare alla fine del problema qui? Immagino che potrebbe essere o JRuby oggetti che non vengono ripuliti, o qualcosa nel ponte Java o nel Garbage collector che non fa il suo lavoro ...

Anche se ho lasciato il processo in esecuzione per mezz'ora , la memoria non va giù ...

  • C'è un modo per sapere quali oggetti sono vivi?
  • Ci sono strumenti gratuiti che sono facili da usare con i quali posso avere maggiori informazioni su chi sta utilizzando tutta la memoria?

A proposito, ho già configurato il server Tomcat di utilizzare più memoria, ma questo è solo un errore di ritardare lo spazio di heap ...

EDIT: Quello che sto vedendo in realtà è che Tomcat utilizza solo tutta la memoria che può utilizzare al massimo (Maximum memory pool). E non lo rilascia mai. Forse è solo un comportamento normale ... Ora ho impostato un massimo di 256 MB ad esempio e nel Task Manager, la memoria rimane intorno ai 256 MB.

EDIT:

Quando si crea un heap dump e lasciando eclissi analizzarlo con la Memory Analyzer Eclipse Questa è la relazione che sto ottenendo. Penso che sia normale dal momento che lo strumento probabilmente non si aspetta tutta la storia JRuby ...

Problema Suspect 1

6.458 istanze di "org.jruby.RubyClass", caricati da "org.apache. catalina.loader.WebappClassLoader @ 0x700ec6988 "occupa 56.969.616 (31,78%) byte.

Parole org.apache.catalina.loader.WebappClassLoader @ 0x700ec6988 org.jruby.RubyClass

Problema Suspect 2

10,597 istanze di "org.jruby.internal.runtime.methods. DefaultMethod ", caricato da" org.apache.catalina.loader.WebappClassLoader @ 0x700ec6988 "occupa 22.182.112 (12,37%) byte.

Parole chiave org.jruby.internal.runtime.methods.DefaultMethod org.apache.catalina.loader.WebappClassLoader @ 0x700ec6988

Problemi Suspect 3

3,144 istanze di "org.jruby.RubyModule", caricato da "org.apache.catalina.loader.WebappClassLoader @ 0x700ec6988" occupare 21.226.816 (11,84 %) byte.

Parole org.apache.catalina.loader.WebappClassLoader @ 0x700ec6988 org.jruby.RubyModule

Problema Suspect 4

8,888 istanze di "org.jruby.MetaClass", caricati dal " org.apache.catalina.loader.WebappClassLoader @ 0x700ec6988 "occupa 18.563.784 (10,35%) byte.

Parole org.jruby.MetaClass org.apache.catalina.loader.WebappClassLoader @ 0x700ec6988

+0

Qual è il problema specifico? Ti manca la memoria? Quale versione di JRuby? Quale versione di Rails? Ecc. Non c'è un "3,7" di nessuno di quelli. –

+0

Il problema specifico era: ERRORE Java Heap Space. Non c'erano più informazioni nei log. –

+0

Aggiornerò la mia domanda con tutta la versione specifica. –

risposta

1

Questa puzza un po 'come perdita di memoria. Non è una bella vista.

Se non c'è molto codice, controllare prima a occhio, che si stanno chiudendo connessioni e flussi e tutti gli oggetti con metodo close. Se questo problema si presenta di recente, dai un'occhiata al codice modificato per ultimo.

Un'altra cosa che vorrei provare è un'ispezione del codice con some tool.

Forse scrivere alcuni test per accelerare la perdita (come le richieste di generazione), è quindi possibile provare a escludere il codice dall'applicazione, fino a trovare l'area che sta causando perdite.

Non è consigliabile controllare gli oggetti in memoria poiché si tratta di un processo lento e doloroso.

1

Prima di tutto: lo spazio Heap di 256 M non è molto per le applicazioni Java, in particolare perché sono coinvolti un contenitore di servizi/app server completamente in esecuzione e (probabilmente) molte librerie.

Java in genere non restituisce la memoria al sistema operativo - una volta allocata, la memoria è considerata di proprietà della JVM. Credo che potrebbero esserci alcune implementazioni della gestione della memoria che restituiscono memoria, ma non le ho mai viste. La mia raccomandazione tipica negli ambienti di produzione è di avere -Xmx uguale -Xms in ogni caso (allocare tutta la memoria che si desidera che JVM sia in grado di allocare immediatamente)

L'esaurimento dello spazio di heap è un segnale per uno dei due (o più) condizioni: a) Si dispone di un'applicazione con una perdita di memoria, b) non si sta allocando abbastanza per la domanda dell'applicazione.

Aumentare l'allocazione di memoria per JVM e monitorare l'utilizzo della memoria e la garbage collection per escludere b) - se si può affermare che l'applicazione ha memoria sufficiente per le proprie esigenze, cercare a) e individuare la causa principale per perdita di memoria. È meglio usare un profiler per questo, ma con 256M di memoria, c'è una grande possibilità che tu non abbia abbastanza memoria.

Problemi correlati