Issue Details (XML | Word | Printable)

Key: POOL-86
Type: Bug Bug
Status: Resolved Resolved
Resolution: Fixed
Priority: Major Major
Assignee: Phil Steitz
Reporter: Mike Martin
Votes: 1
Watchers: 1
Operations

If you were logged in you would be able to see more operations.
Commons Pool

GenericKeyedObjectPool retaining too many idle objects

Created: 10/Oct/06 11:01 PM   Updated: 08/Dec/07 08:52 AM
Return to search
Component/s: None
Affects Version/s: 1.3
Fix Version/s: 2.0

Time Tracking:
Not Specified

File Attachments:
  Size
Text File Licensed for inclusion in ASF works pool-86.patch 2006-10-30 08:15 PM Mike Martin 2 kB
Text File Licensed for inclusion in ASF works pool-86.withtest.patch 2006-10-30 09:07 PM Mike Martin 4 kB

Resolution Date: 07/Oct/07 12:09 AM


 Description  « Hide
There are two somewhat related problems in GenericKeyedObjectPool that cause
many more idle objects to be retained than should be, for much longer than they
should be.

Firstly, borrowObject() is returning the LRU object rather than the MRU object.
That minimizes rather than maximizes object reuse and tends to refresh all the
idle objects, preventing them from becoming evictable.

The idle LinkedList is being maintained with:

borrowObject: list.removeFirst()
returnObject: list.addLast()

These should either both be ...First() or both ...Last() so the list maintains
a newer-to-older, or vice-versa, ordering. The code in evict() works from the
end of the list which indicates newer-to-older might have been originally
intended.

Secondly, evict() itself has a couple of problems, both of which only show up
when many keys are in play:

1. Once it processes a key it doesn't advance to the next key.

2. _evictLastIndex is not working as documented ("Position in the _pool where
the _evictor last stopped"). Instead it's the position where the last scan
started, and becomes the position at which it attempts to start scanning
in the next pool. That just causes objects eligible for eviction to
sometimes be skipped entirely.

Here's a patch fixing both problems:

GenericKeyedObjectPool.java
990c990
< pool.addLast(new ObjectTimestampPair(obj));

> pool.addFirst(new ObjectTimestampPair(obj));
1094,1102c1094,1095
< }
<
< // if we don't have a keyed object pool iterator
< if (objIter == null) {
< final LinkedList list = (LinkedList)_poolMap.get(key);
< if (_evictLastIndex < 0 || _evictLastIndex > list.size()) { < _evictLastIndex = list.size(); < }
< objIter = list.listIterator(_evictLastIndex);

> LinkedList list = (LinkedList)_poolMap.get(key);
> objIter = list.listIterator(list.size());
1154,1155c1147
< _evictLastIndex = -1;
< objIter = null;

> key = null;
1547,1551d1538
<
< /**
< * Position in the _pool where the _evictor last stopped.
< */
< private int _evictLastIndex = -1;

I have a local unit test for this but it depends on some other code I can't
donate. It works like this:

1. Fill the pool with _maxTotal objects using many different keys.
2. Select X as a small number, e.g. 2.
3. Compute:
maxEvictionRunsNeeded = (maxTotal - X) / numTestsPerEvictionRun + 2;
maxEvictionTime = minEvictableIdleTimeMillis + maxEvictionRunsNeeded * timeBetweenEvictionRunsMillis;
4. Enter a loop:
a. Borrow X objects.
b. Exit if _totalIdle = 0
c. Return the X objects.

Fail if loop doesn't exit within maxEvictionTime.

Mike



 All   Comments   Work Log   Change History   Subversion Commits      Sort Order: Ascending order - Click to sort in descending order
Sandy McArthur made changes - 30/Oct/06 04:18 AM
Field Original Value New Value
Assignee Sandy McArthur [ sandymac ]
Mike Martin made changes - 30/Oct/06 08:15 PM
Attachment pool-86.patch [ 12343956 ]
Mike Martin made changes - 30/Oct/06 09:07 PM
Attachment pool-86.withtest.patch [ 12343958 ]
Sandy McArthur made changes - 13/Nov/06 01:41 AM
Fix Version/s Nightly Builds [ 12311772 ]
Resolution Fixed [ 1 ]
Status Open [ 1 ] Resolved [ 5 ]
Henri Yandell made changes - 18/Feb/07 05:40 PM
Fix Version/s Nightly Builds [ 12311772 ]
Fix Version/s 2.0 [ 12311985 ]
Phil Steitz made changes - 21/Jun/07 10:44 PM
Status Resolved [ 5 ] Reopened [ 4 ]
Resolution Fixed [ 1 ]
Assignee Sandy McArthur [ sandymac ] Phil Steitz [ psteitz ]
Phil Steitz made changes - 07/Oct/07 12:09 AM
Resolution Fixed [ 1 ]
Status Reopened [ 4 ] Resolved [ 5 ]