<< Back to previous view

[OSCACHE-4] Concurrent issue for LRU, cache size exceed default max cachesize Created: 15/Feb/12  Updated: 15/Feb/12

Status: Open
Project: oscache
Component/s: None
Affects Version/s: None
Fix Version/s: None

Type: Bug Priority: Major
Reporter: fightf Assignee: Unassigned
Resolution: Unresolved Votes: 0
Remaining Estimate: Not Specified
Time Spent: Not Specified
Original Estimate: Not Specified
Environment:

centos+tomcat7


Tags:
Participants: fightf

 Description   

OSCache version is 2.4.1

Precondition:
We use oscache to cache ibatis resultset, default max cache size is "1000" and the cache algorithm is LRU.
We do one performance testing for our application. our app call get/put/flush method to update the resultset.

Except result
The performance keep good.

Actually Result
The performance is bad when run serials times, we debug it and find the cache size growth very quickly, it will growth to 10000, this number is larger than the default max size.

And we analyze the oscache code and find there is one issue in LRU algorithm.
When cache size is full, LRU cache key sequence is "Key1-> Key2->Key3->Key4...KeyN-1"
Thread A want to push one value to the cache with KeyN, it will entry synchronized statement to prepare remove the Key1 and it's value.
at the same time, Thread B use Key1 to get the object from cachemap before , as LRU requirement, we must move key1 to the end of the queue. But actually the key1 already be removed by Thread A.
That will cause LRU key's list size is large than cachemap size.

The error code in LRUCache.java
protected void itemRetrieved(Object key) {
....
synchronized (list) { list.remove(key); list.add(key); }
}
My solution is "add one protection"
protected void itemRetrieved(Object key) {
....
synchronized (list) {
if(list. contains(key)){ list.remove(key); list.add(key); }
}
}






Generated at Wed Apr 16 23:20:15 UTC 2014 using JIRA 4.0.2#472.