[
https://issues.apache.org/jira/browse/OFBIZ-2186?page=com.atlassian.jira.plugin.system.issuetabpanels:comment-tabpanel&focusedCommentId=12673321#action_12673321
]
Philippe Mouawad commented on OFBIZ-2186:
-----------------------------------------
Hello M. Jones,
If you don't think that my arguments are correct, can you explain why ?
I agree with you about the synchronization performance loss but is it acceptable
that this absence of synchronization provokes a server crash through OOM ?
I will propose another solution soon based on another implementation of LRU but
meanwhile we will put this in production and come back with results.
Now about my explanation, since a LRU is used, LRU is computed based on get(),
look at the code of LinkedHashMap and you will see that get() modifies the state
of the Map, if so Synchronization is mandatory.
Tell me what kind of info you need to be convinced.
To be more convinced run the program I attach with the following options on a
JDK 5:
-Xmx5m -XX:+HeapDumpOnOutOfMemoryError -XX:HeapDumpPath=C:/temp/
It will throw an OutOfMemory.
Add synchronized to CacheLineUsage#get() and see NO MORE PROBLEM.
Inspect the Heap Dump and you get exactly what I told you:
size of Map is 31362 while maxSize is 5000
Memory occupation is 6056872
> OutOfMemory provoked by Cache overflow
> --------------------------------------
>
> Key: OFBIZ-2186
> URL: https://issues.apache.org/jira/browse/OFBIZ-2186
> Project: OFBiz
> Issue Type: Bug
> Components: framework
> Affects Versions: SVN trunk, Release Branch 4.0
> Environment: Linux, JDK 1.5_15, Xmx set to 1156Mo
> Reporter: Philippe Mouawad
> Priority: Critical
> Attachments: CacheLineTable-patch.txt
>
>
> In our production system, we had an OutOfMemoryError.
> I analyzed the generated Heap Dump and found the following:
> The cache entitycache.entity-list.default.ProductCategoryMember retains a
> heap of 369314128 Bytes.
> The LRUMap hold by this object is occupying this space (369314128) and this
> object has a stange state:
> - maxSize is set to 5000 (as set in the cache.properties)
> - size is 128930 => PROBLEM
> IN cache.properties:
> entitycache.entity-list.default.ProductCategoryMember.expireTime=3600000
> entitycache.entity-list.default.ProductCategoryMember.useSoftReference=true
> entitycache.entity-list.default.ProductCategoryMember.maxInMemory=5000
> entitycache.entity-list.default.ProductCategoryMember.maxSize=7500
> I analyzed the code of LRUMap and its usage in CacheLineTable and IMHO the
> bug is a missing synchonized in get():
> public CacheLine<V> get(Object key) {
> if (key == null) {
> if (Debug.verboseOn()) Debug.logVerbose("In CacheLineTable tried
> to get with null key, using NullObject" + this.cacheName, module);
> }
> return getNoCheck(key);
> }
> Since LRUMap extends LinkedHashMap, if you look at get method, it changes the
> state of the Map by calling e.recordAccess(this):
> public V get(Object key) {
> Entry<K,V> e = (Entry<K,V>)getEntry(key);
> if (e == null)
> return null;
> e.recordAccess(this);
> return e.value;
> }
> So the default of synchronization corrupts the state of LRUMap which grows
> indefinitely
> I will submit a patch for this on the trunk.
> Philippe
> www.ubik-ingenierie.com
--
This message is automatically generated by JIRA.
-
You can reply to this email to add a comment to the issue online.