[
https://issues.jboss.org/browse/ISPN-1822?page=com.atlassian.jira.plugin....
]
Martin Gencur edited comment on ISPN-1822 at 9/19/12 8:23 AM:
--------------------------------------------------------------
After more debugging, I got to the root cause. The problem is in IBM's implementation
of LinkedHashMap. The LinkedHashMap holds its data in an array called elementData. When
LinkedHashMap calls putImpl and the number of elements in the array is higher than the
limit, it performs a rehash. The next call to createHashedEntry() (inside putImpl) creates
a new entry but this entry is sometimes stored in a place of an existing element (due to
incorrectly generated hash/index value) instead of appending it to the elementData array.
As a result, the LinkedHashMap holds wrong data (e.g. 2 elements instead of 3, and wrong
ones) and the consecutive call to removeEldestEntry returns true which means that another
element is removed from the elementData array at the end of putImpl() in LinkedHashMap
(i.e. elementData contains 1 element instead of 2, and wrong one).
We spotted this defect only with small numbers of elements in the cache. However, the
nature of the defect signifies that this could easily happen even with higher number of
elements in the cache and thus evicting wrong entries.
I cannot see any obvious fix/workaround for Infinispan, apart from fixing the bug in IBM
JDK. Or rewriting the whole LRU class without using LinkedHashMap. So I would suggest not
using eviction with IBM JDK (only for LRU, LIRS works well because it does not extend
LinkedHashMap).
The suspected code in IBM's LinkedHashMap:
https://gist.github.com/3749342
was (Author: mgencur):
After more debugging, I got to the root cause. The problem is in IBM's
implementation of LinkedHashMap. The LinkedHashMap holds its data in an array called
elementData. When LinkedHashMap calls putImpl and the number of elements in the array is
higher than the limit, it performs a rehash. The next call to createHashedEntry() (inside
putImpl) creates a new entry but this entry is sometimes stored in a place of an existing
element (due to incorrectly generated hash/index value) instead of appending it to the
elementData array.
As a result, the LinkedHashMap holds wrong data (e.g. 2 elements instead of 3, and wrong
ones) and the consecutive call to removeEldestEntry returns true which means that another
element is removed from the elementData array at the end of putImpl() in LinkedHashMap
(i.e. elementData contains 1 element instead of 2, and wrong one).
We spotted this defect only with small numbers of elements in the cache. However, the
nature of the defect signifies that this could easily happen even with higher number of
elements in the cache and thus evicting wrong entries.
I cannot see any obvious fix/workaround for Infinispan, apart from fixing the bug in IBM
JDK. So I would suggest not using eviction with IBM JDK.
The suspected code in IBM's LinkedHashMap:
https://gist.github.com/3749342
Cache entry not evicted from memory on IBM JDK when another entry was
loaded from a cache loader and maxEntries had been reached
--------------------------------------------------------------------------------------------------------------------------------
Key: ISPN-1822
URL:
https://issues.jboss.org/browse/ISPN-1822
Project: Infinispan
Issue Type: Bug
Components: Eviction
Affects Versions: 5.1.0.FINAL
Environment: java version "1.6.0"
Java(TM) SE Runtime Environment (build pxi3260sr9fp1-20110208_03(SR9 FP1))
IBM J9 VM (build 2.4, JRE 1.6.0 IBM J9 2.4 Linux x86-32 jvmxi3260sr9-20110203_74623 (JIT
enabled, AOT enabled) ;
java version "1.7.0"
Java(TM) SE Runtime Environment (build pxi3270-20110827_01)
IBM J9 VM (build 2.6, JRE 1.7.0 Linux x86-32 20110810_88604 (JIT enabled, AOT enabled)
Reporter: Martin Gencur
Assignee: Martin Gencur
Fix For: 5.2.0.Final
This behavior is specific to IBM JDK (I tried JDK6 and 7), it works fine with Java
HotSpot.
Steps to reproduce the problem:
1) set maxEntries for eviction to 2 and algorithm e.g. to LRU
2) store 3 entries key1, key2, key3 to the cache (after that you can see that the cache
contains only 2 entries - key2 and key3, the first one was evicted from memory)
3) call cache.get("key1")
4) PROBLEM - cache contains all key1, key2, key3 even though it should contain only 2
entries - only happens with IBM JDK (6 or 7 ..no matter)
I'll shortly issue a pull request with a test to ispn-core
--
This message is automatically generated by JIRA.
If you think it was sent incorrectly, please contact your JIRA administrators
For more information on JIRA, see:
http://www.atlassian.com/software/jira