[ 
https://issues.apache.org/jira/browse/JXPATH-195?page=com.atlassian.jira.plugin.system.issuetabpanels:all-tabpanel
 ]

Stephan Birkl updated JXPATH-195:
---------------------------------
    Description: 
JXPathContextReferenceImpl caches already compiled expressions in a static 
HashMap. This map holds the compiled expressions as SoftReference. The map has 
no size limit but the cleanup strategy is that every 500 puts the map is 
scanned whether values have been already collected by gc (soft refs) and in 
this case removed from the map completely.

There is also a static feature toggle in code (but not accessible via 
configuration) to not use the soft references feature - but in this case the 
map is not bounded and not cleaned up at all.

In our use case the SoftReference cleanup strategy has some major disadvantages:
 * At least when using Oracle JDK 8, SoftReferences are only cleaned up when a 
full GC occurs (for example because of an OOM error)
 * Our application uses G1GC that is tuned to basically never perform a full 
GC, so a clean up never happens under normal operation
 * So waiting for a full GC is definitely too late. For example I've found 3.2 
mio entries in a heap dump of our application, taking about 4 GB of old gen 
heap memory. Application performance already degraded because this caused 
frequent old gen GC activities, but SoftReferences were not cleaned up yet
 * This problem is of course application and use case specific - what I want to 
point out is that the current cleanup strategy can cause problems depending on 
the environment.

Attached is a patch against the current master. It keeps the current behavior 
by default but adds / changes the following:
 * Adds a system property "jxpath.softcache" to enable or disable the softcache 
feature. Default is enabled. It basically makes the already existing static 
feature toggle USE_SOFT_CACHE configurable.
 * If softcache feature is disabled it uses a bounded LRU Map instead of an 
unbounded HashMap to limit the cache size this way. The implementation uses 
java builtin LinkedHashMap to not introduce new dependencies.
 * The size limit in case of soft cache disables can be configured via system 
property "jxpath.cache.size". The default is 100 which is perfect for our use 
case but may be too small for other use cases. I'm definitely fine if you 
decide that a higher number would be better as default.

  was:
JXPathContextReferenceImpl caches already compiled expressions in a static 
HashMap_._ This map holds the compiled expressions as SoftReference. The map 
has no size limit but the cleanup strategy is that every 500 puts the map is 
scanned whether values have been already collected by gc (soft refs) and in 
this case removed from the map completely.

There is also a static feature toggle in code (but not accessible via 
configuration) to not use the soft references feature - but in this case the 
map is not bounded and not cleaned up at all.

In our use case the SoftReference cleanup strategy has some major disadvantages:
 * At least when using Oracle JDK 8, SoftReferences are only cleaned up when a 
full GC occurs (for example because of an OOM error)
 * Our application uses G1GC that is tuned to basically never perform a full 
GC, so a clean up never happens under normal operation
 * So waiting for a full GC is definitely too late. For example I've found 3.2 
mio entries in a heap dump of our application, taking about 4 GB of old gen 
heap memory. Application performance already degraded because this caused 
frequent old gen GC activities, but SoftReferences were not cleaned up yet
 * This problem is of course application and use case specific - what I want to 
point out is that the current cleanup strategy can cause problems depending on 
the environment.

Attached is a patch against the current master. It keeps the current behavior 
by default but adds / changes the following:
 * Adds a system property "jxpath.softcache" to enable or disable the softcache 
feature. Default is enabled. It basically makes the already existing static 
feature toggle USE_SOFT_CACHE configurable.
 * If softcache feature is disabled it uses a bounded LRU Map instead of an 
unbounded HashMap to limit the cache size this way. The implementation uses 
java builtin LinkedHashMap to not introduce new dependencies.
 * The size limit in case of soft cache disables can be configured via system 
property "jxpath.cache.size". The default is 100 which is perfect for our use 
case but may be too small for other use cases. I'm definitely fine if you 
decide that a higher number would be better as default.


> JXPathContextReferenceImpl soft cache can cause OOM
> ---------------------------------------------------
>
>                 Key: JXPATH-195
>                 URL: https://issues.apache.org/jira/browse/JXPATH-195
>             Project: Commons JXPath
>          Issue Type: Bug
>    Affects Versions: 1.3, 1.4
>            Reporter: Stephan Birkl
>            Priority: Major
>              Labels: patch
>         Attachments: JXPathContextReferenceImpl.java.patch
>
>
> JXPathContextReferenceImpl caches already compiled expressions in a static 
> HashMap. This map holds the compiled expressions as SoftReference. The map 
> has no size limit but the cleanup strategy is that every 500 puts the map is 
> scanned whether values have been already collected by gc (soft refs) and in 
> this case removed from the map completely.
> There is also a static feature toggle in code (but not accessible via 
> configuration) to not use the soft references feature - but in this case the 
> map is not bounded and not cleaned up at all.
> In our use case the SoftReference cleanup strategy has some major 
> disadvantages:
>  * At least when using Oracle JDK 8, SoftReferences are only cleaned up when 
> a full GC occurs (for example because of an OOM error)
>  * Our application uses G1GC that is tuned to basically never perform a full 
> GC, so a clean up never happens under normal operation
>  * So waiting for a full GC is definitely too late. For example I've found 
> 3.2 mio entries in a heap dump of our application, taking about 4 GB of old 
> gen heap memory. Application performance already degraded because this caused 
> frequent old gen GC activities, but SoftReferences were not cleaned up yet
>  * This problem is of course application and use case specific - what I want 
> to point out is that the current cleanup strategy can cause problems 
> depending on the environment.
> Attached is a patch against the current master. It keeps the current behavior 
> by default but adds / changes the following:
>  * Adds a system property "jxpath.softcache" to enable or disable the 
> softcache feature. Default is enabled. It basically makes the already 
> existing static feature toggle USE_SOFT_CACHE configurable.
>  * If softcache feature is disabled it uses a bounded LRU Map instead of an 
> unbounded HashMap to limit the cache size this way. The implementation uses 
> java builtin LinkedHashMap to not introduce new dependencies.
>  * The size limit in case of soft cache disables can be configured via system 
> property "jxpath.cache.size". The default is 100 which is perfect for our use 
> case but may be too small for other use cases. I'm definitely fine if you 
> decide that a higher number would be better as default.



--
This message was sent by Atlassian JIRA
(v7.6.3#76005)

Reply via email to