Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

RythmEngine and TemplateClassManager the Biggest Objects of the heap : memory leak problems

In my company, we are using Rythm due to its facility and easy use in a project. In our project, we are sending several e-mails (1000-2000 emails by day); the e-mail template is a Rythm template with dynamic syntax (Java code). Performance seems fine and it passed the integration tests.

Nevertheless, we have experimented several memory problems that drives to a memory leak after 3-4 days. Profiling, we have observed that Rythm is the most biggest object of the heap (our profilings are about 1 day) even more than the ClassLoader or the BeanFactory from Spring.

Using heap tools analyzer, we have observed that RythmEngine and TemplateClassManager are the biggest objects

 (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

......

We can see from the heap analyzer tools that these objects are big ones, and it seems that they increase during time.

enter image description here

And a GC Root.

enter image description here

Concerning memory pools: Par Eden seems fine and CMS Old Generation seems not to increase, or at least slowly (even after some major GCs it seems that free memory). Heap memory seems fine (tests and profiling are about one day), but in production increases slowly after it reaches the maximum heap.

We are asking if someone has experimented this feature (using rythm and after some days a memory leak appears) or just give some best practices of how to improve performance with rythm in a production environment. Or any idea of how to deal with a depth memory leak will be welcomed.

IMPORTANT NOTE [30-09-2015] : We have changed from Rythm to FreeMarker as Template Engine and it seems (as our Monitoring Systems reflects) that memory is more stable and it is about of 20% of max memory (-Xmx1024). We will inform more detailed during this week. But it seems that Rythm might have some memory problems that it drives to a memory leak after a couple of days.

IMPORTANT NOTE [06-10-2015] : After some days of intensive monitoring we have checked that memory is stable using FreeMarker as Template Engine. We have removed all the dependencies of Rythm in our product because as our studies reflects it has a potential memory leak problem not solved which drives to a OOME for heap after some days (in our case two days). Issue closed.

like image 646
Francesc Xavier Avatar asked Aug 13 '15 15:08

Francesc Xavier


1 Answers

We have as well faced and came across such issue but its because of compilation of templates again and again. To avoid this we did the below settings, Enable prod mode Enable template caching Set the template compiled directory location - to store the compiled version of template files. (Dont confuse with template directory configuration) which will boost your application speed.

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);
like image 147
Hakuna Matata Avatar answered Oct 22 '22 16:10

Hakuna Matata