2015-08-13 12 views
23

Nella mia azienda, stiamo utilizzando Rythm per la sua facilità e facilità d'uso in un progetto. Nel nostro progetto, inviamo diverse e-mail (1000-2000 email di giorno); il modello e-mail è un modello Rythm con sintassi dinamica (codice Java). Le prestazioni sembrano soddisfacenti e hanno superato i test di integrazione.RythmEngine e TemplateClassManager gli oggetti più grandi dell'heap: problemi di perdita di memoria

Tuttavia, abbiamo sperimentato diversi problemi di memoria che causano perdite di memoria dopo 3-4 giorni. Profilazione, abbiamo osservato che il Rythm è l'oggetto più grande dell'heap (i nostri profili sono circa 1 giorno) ancor più del ClassLoader o del BeanFactory di Spring.

L'utilizzo di strumenti di heap analizzatore, abbiamo osservato che RythmEngine e TemplateClassManager sono gli oggetti più grandi

(Instance) - (retained size bytes) 

org.rythmengine.RythmEngine#1 - 10,192,894 
org.rythmengine.internal.compiler.TemplateClassManager#1 - 9,223,065 
org.springframework.boot.loader.LaunchedURLClassLoader#1 - 6,975,661 
java.util.Vector#89 - 6,378,290 
java.lang.Object[]#7549 - 6,378,254 
org.springframework.beans.factory.support.DefaultListableBeanFactory#1 - 3,741,643 

...... 

Possiamo vedere dagli strumenti analizzatore di heap che questi oggetti sono quelli più grandi, e sembra che aumentano nel tempo.

enter image description here

E un GC Root.

enter image description here

Per quanto riguarda i pool di memoria: Par Eden sembra che vada bene e CMS vecchia generazione sembra non aumentare, o per lo meno lentamente (anche dopo alcuni importanti GC sembra che la memoria libera). La memoria heap sembra soddisfacente (i test e il profiling sono circa un giorno), ma in produzione aumenta lentamente dopo aver raggiunto l'heap massimo.

Stiamo chiedendo se qualcuno ha sperimentato questa funzione (utilizzando il ritmo e dopo alcuni giorni appare una perdita di memoria) o semplicemente dare alcune buone pratiche su come migliorare le prestazioni con il ritmo in un ambiente di produzione. O qualsiasi idea di come affrontare una perdita di memoria di profondità sarà accolta favorevolmente.

NOTA IMPORTANTE [30-09-2015]: Abbiamo cambiato da Rythm a FreeMarker come Template Engine e sembra (come i nostri sistemi di controllo riflette) che memoria è più stabile ed è circa del 20 % della memoria massima (-Xmx1024). Informeremo più dettagliatamente durante questa settimana. Ma sembra che Rythm potrebbe avere alcuni problemi di memoria che causa una perdita di memoria dopo un paio di giorni.

NOTA IMPORTANTE [2015/06/10]: Dopo alcuni giorni di monitoraggio intensivo abbiamo verificato che la memoria è stabile utilizzando FreeMarker come modello del motore. Abbiamo rimosso tutte le dipendenze di Rythm nel nostro prodotto perché i nostri studi riflettono lo che ha un potenziale problema di perdita di memoria non risolto che passa a OOME per heap dopo alcuni giorni (nel nostro caso due giorni). Problema chiuso

+1

Sto solo cercando di chiarire che cosa è successo, abbiamo trovato questo problema (https://github.com/greenlaw110/Rythm/issues/199) di GitHub. È stato dimostrato che una perdita di memoria era dovuta all'implementazione di org.rythmengine.DefaultShutdownService (che registrava un hook di chiusura). Ma è stato commentato questo componente. È piuttosto strano, perché il profiling mostra solo che questi oggetti sono grandi nelle dimensioni mantenute e sembra che aumenti nel tempo (ma lentamente). Diversi dubbi e non molta documentazione. –

+1

Ho Rythm in esecuzione in un progetto di banca per mesi e nessun problema di memoria trovato. La tua istanza RythmEngine è in esecuzione in modalità PROD o DEV? Una cosa interessante è da dove provengono quegli aspetti? Rythm non li usa? A proposito, puoi caricare il file di immagine della memoria da qualche parte in modo da poter dare uno sguardo approfondito al problema? Disclaim: Io sono l'autore del motore Rythm –

+1

L'altra domanda che voglio porre è quante istanze di Rythm hai nella tua JVM? –

risposta

0

Abbiamo anche affrontato e riscontrato tale problema, ma è dovuto alla compilazione di modelli ancora e ancora. Per evitare ciò abbiamo fatto le seguenti impostazioni, Abilita modalità prod Abilita memorizzazione nella cache del modello Imposta il percorso della directory compilata del modello - per memorizzare la versione compilata dei file modello. (Non confondere con la configurazione della directory del modello) che aumenterà la velocità dell'applicazione.

Map<String, Object> rythmConfigs = new HashMap<>(); 
     //rythmConfigs.put(ENGINE_MODE, this.appMode ? "prod" : "dev"); 
     rythmConfigs.put(PRECOMPILE_MODE_ENABLED, this.config.getBoolean(PRECOMPILE_MODE_ENABLED, true)); 
     rythmConfigs.put(LOAD_PRECOMPILED_ENABLED, this.config.getBoolean(LOAD_PRECOMPILED_ENABLED, true)); 
     rythmConfigs.put("rythm.default.cache_ttl", Integer.MAX_VALUE); 
     rythmConfigs.put("rythm.cache.enable", this.appMode); 
     //rythmConfigs.put("cache.prod_only.enabled", this.appMode); 
     rythmConfigs.put(PRECOMPILED_DIR, getTempDir(config.getString(XoAppConfigKeys.APPLICATION_CONTEXT)).getAbsolutePath()); 
     rythmConfigs.put(TEMPLATE_DIR, this.templateFolderUri.getPath()); 
     rythmEngine = new RythmEngine(rythmConfigs);