Return-Path: Delivered-To: apmail-commons-issues-archive@locus.apache.org Received: (qmail 30883 invoked from network); 8 Dec 2007 08:54:13 -0000 Received: from hermes.apache.org (HELO mail.apache.org) (140.211.11.2) by minotaur.apache.org with SMTP; 8 Dec 2007 08:54:13 -0000 Received: (qmail 38357 invoked by uid 500); 8 Dec 2007 08:53:56 -0000 Delivered-To: apmail-commons-issues-archive@commons.apache.org Received: (qmail 38134 invoked by uid 500); 8 Dec 2007 08:53:55 -0000 Mailing-List: contact issues-help@commons.apache.org; run by ezmlm Precedence: bulk List-Help: List-Unsubscribe: List-Post: List-Id: Reply-To: issues@commons.apache.org Delivered-To: mailing list issues@commons.apache.org Received: (qmail 37768 invoked by uid 99); 8 Dec 2007 08:53:55 -0000 Received: from nike.apache.org (HELO nike.apache.org) (192.87.106.230) by apache.org (qpsmtpd/0.29) with ESMTP; Sat, 08 Dec 2007 00:53:55 -0800 X-ASF-Spam-Status: No, hits=-100.0 required=10.0 tests=ALL_TRUSTED X-Spam-Check-By: apache.org Received: from [140.211.11.4] (HELO brutus.apache.org) (140.211.11.4) by apache.org (qpsmtpd/0.29) with ESMTP; Sat, 08 Dec 2007 08:54:04 +0000 Received: from brutus (localhost [127.0.0.1]) by brutus.apache.org (Postfix) with ESMTP id 1F9F471424F for ; Sat, 8 Dec 2007 00:53:43 -0800 (PST) Message-ID: <12981526.1197104023106.JavaMail.jira@brutus> Date: Sat, 8 Dec 2007 00:53:43 -0800 (PST) From: "Mark Thomas (JIRA)" To: issues@commons.apache.org Subject: [jira] Commented: (POOL-86) GenericKeyedObjectPool retaining too many idle objects MIME-Version: 1.0 Content-Type: text/plain; charset=utf-8 Content-Transfer-Encoding: 7bit X-Virus-Checked: Checked by ClamAV on apache.org [ https://issues.apache.org/jira/browse/POOL-86?page=com.atlassian.jira.plugin.system.issuetabpanels:comment-tabpanel#action_12549673 ] Mark Thomas commented on POOL-86: --------------------------------- I've looked through the code and the patch looks good to me. > GenericKeyedObjectPool retaining too many idle objects > ------------------------------------------------------ > > Key: POOL-86 > URL: https://issues.apache.org/jira/browse/POOL-86 > Project: Commons Pool > Issue Type: Bug > Affects Versions: 1.3 > Reporter: Mike Martin > Assignee: Phil Steitz > Fix For: 2.0 > > Attachments: pool-86.patch, pool-86.withtest.patch > > > 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 -- This message is automatically generated by JIRA. - You can reply to this email to add a comment to the issue online.