You are viewing a plain text version of this content. The canonical link for it is here.
Posted to issues@commons.apache.org by "Jarek Jarcec Cecho (JIRA)" <ji...@apache.org> on 2016/09/23 22:40:21 UTC

[jira] [Commented] (EL-1) [el] Memory Leak: EL Cache entries never removed.

    [ https://issues.apache.org/jira/browse/EL-1?page=com.atlassian.jira.plugin.system.issuetabpanels:comment-tabpanel&focusedCommentId=15517771#comment-15517771 ] 

Jarek Jarcec Cecho commented on EL-1:
-------------------------------------

I believe that we hit this bug as well in our project. We have one JVM where we're having a lot of various (and sometimes even half generated) expressions and I've noticed that the internal caches in {{ExpressionEvaluatorImpl}} can grow without any limitations - check out details on our [JIRA  SDC-4033|https://issues.streamsets.com/browse/SDC-4033] if you're interested - the summary is that after approx. a day of running the cache occupied 84% of heap and consumed more then 6GB of ram :(

I'm happy to take a stab at fixing this, but I'm not sure what would community prefer me to do. Couple of brainstorming ideas:

* The class {{ExpressionEvaluatorImpl}} currently takes a {{boolean}} argument in constructor called {{pBypassCache}} that indicates "flag indicating if the cache should be bypassed". Sadly this flag only causes the class to not use the cache for reading (checking if this expression was already seen), but [it will be used for storing regardless of the actual value of this flag|https://github.com/apache/commons-el/blob/trunk/src/java/org/apache/commons/el/ExpressionEvaluatorImpl.java#L267]. It seems fairly non-controversal to use this existing flag to stop writing values to the cache if the flag is set to false?
* Another idea is to use a {{LRUMap}} instead normal {{HashMap}} - this way the size would be limited and would not grow indefinitely. It seems potentially controversial though as {{commons-el}} doesn't have a lot of dependencies and I'm not sure if the community would be open to add dependency on let say {{commons-collections}} to get {{LRUMap}} implementation. It could be shaded to avoid leaking it to users, but it's still another (and fairly sizable) dependency.
* Last but not least, perhaps we can expose methods {{cacheSize}} and {{cleanUpCaches}} that user code can use to  control the size?


> [el] Memory Leak: EL Cache entries never removed.
> -------------------------------------------------
>
>                 Key: EL-1
>                 URL: https://issues.apache.org/jira/browse/EL-1
>             Project: Commons EL
>          Issue Type: Bug
>    Affects Versions: 1.0
>         Environment: Operating System: All
> Platform: All
>            Reporter: Bill Alexander
>
> This bug refers to the two caches on ExpressionEvaluatorImpl,
> sCachedExpressionStrings, but primarily sCachedExpectedTypes.
> Here is a use case to illustrate the problem.  A web application typically
> creates 1,000 different objects of classes it defines using the EL language, and
> PropertyEditor's. A Tomcat instance is run with 5 of these web applications.
> Each time one of them is reloaded, a new classloader is created for the web
> application, so a new set of 1,000 objects is created in the cache.  The old
> objects, and objects they point to (e.g. class and classloader objects), are
> never garbage collected. The only way to recover the associated memory is to
> stop and restart Tomcat.
> There are many possible solutions.  A simple one would be to age instances out
> of the caches after a fixed period of time (say one hour). It would be nice if
> whatever cache controls are provided are configurable.



--
This message was sent by Atlassian JIRA
(v6.3.4#6332)