Return-Path: Delivered-To: apmail-db-derby-commits-archive@www.apache.org Received: (qmail 6813 invoked from network); 15 Jan 2008 22:37:15 -0000 Received: from hermes.apache.org (HELO mail.apache.org) (140.211.11.2) by minotaur.apache.org with SMTP; 15 Jan 2008 22:37:15 -0000 Received: (qmail 13650 invoked by uid 500); 15 Jan 2008 22:37:05 -0000 Delivered-To: apmail-db-derby-commits-archive@db.apache.org Received: (qmail 13631 invoked by uid 500); 15 Jan 2008 22:37:05 -0000 Mailing-List: contact derby-commits-help@db.apache.org; run by ezmlm Precedence: bulk list-help: list-unsubscribe: List-Post: Reply-To: "Derby Development" List-Id: Delivered-To: mailing list derby-commits@db.apache.org Received: (qmail 13620 invoked by uid 99); 15 Jan 2008 22:37:05 -0000 Received: from nike.apache.org (HELO nike.apache.org) (192.87.106.230) by apache.org (qpsmtpd/0.29) with ESMTP; Tue, 15 Jan 2008 14:37:05 -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.3] (HELO eris.apache.org) (140.211.11.3) by apache.org (qpsmtpd/0.29) with ESMTP; Tue, 15 Jan 2008 22:36:49 +0000 Received: by eris.apache.org (Postfix, from userid 65534) id 331581A9832; Tue, 15 Jan 2008 14:36:41 -0800 (PST) Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit Subject: svn commit: r612262 - in /db/derby/code/trunk/java: client/org/apache/derby/client/am/SectionManager.java testing/org/apache/derbyTesting/functionTests/master/derbyStress.out testing/org/apache/derbyTesting/functionTests/tests/jdbcapi/derbyStress.java Date: Tue, 15 Jan 2008 22:36:40 -0000 To: derby-commits@db.apache.org From: kmarsden@apache.org X-Mailer: svnmailer-1.0.8 Message-Id: <20080115223641.331581A9832@eris.apache.org> X-Virus-Checked: Checked by ClamAV on apache.org Author: kmarsden Date: Tue Jan 15 14:36:38 2008 New Revision: 612262 URL: http://svn.apache.org/viewvc?rev=612262&view=rev Log: DERBY-3316 Leak in client if ResultSet not closed The leak was in SectionManager.positionedUpdateCursorNameToResultSet_ which kept a reference to the ResultSet so it wouldn't get garbage collected. The solution was to use a WeakReference to the ResultSets in positionedUpdateCursorNameToResultSet_ so that they can be garbage collected. Modified: db/derby/code/trunk/java/client/org/apache/derby/client/am/SectionManager.java db/derby/code/trunk/java/testing/org/apache/derbyTesting/functionTests/master/derbyStress.out db/derby/code/trunk/java/testing/org/apache/derbyTesting/functionTests/tests/jdbcapi/derbyStress.java Modified: db/derby/code/trunk/java/client/org/apache/derby/client/am/SectionManager.java URL: http://svn.apache.org/viewvc/db/derby/code/trunk/java/client/org/apache/derby/client/am/SectionManager.java?rev=612262&r1=612261&r2=612262&view=diff ============================================================================== --- db/derby/code/trunk/java/client/org/apache/derby/client/am/SectionManager.java (original) +++ db/derby/code/trunk/java/client/org/apache/derby/client/am/SectionManager.java Tue Jan 15 14:36:38 2008 @@ -21,6 +21,8 @@ package org.apache.derby.client.am; +import java.lang.ref.WeakReference; + import org.apache.derby.shared.common.reference.JDBC30Translation; import org.apache.derby.shared.common.reference.SQLState; @@ -184,11 +186,12 @@ } void mapCursorNameToResultSet(String cursorName, ResultSet resultSet) { - positionedUpdateCursorNameToResultSet_.put(cursorName, resultSet); + // DERBY-3316. Needs WeakReference so that ResultSet can be garbage collected + positionedUpdateCursorNameToResultSet_.put(cursorName, new WeakReference(resultSet)); } ResultSet getPositionedUpdateResultSet(String cursorName) throws SqlException { - ResultSet rs = (ResultSet) positionedUpdateCursorNameToResultSet_.get(cursorName); + ResultSet rs = (ResultSet) ((WeakReference) (positionedUpdateCursorNameToResultSet_.get(cursorName))).get(); if (rs == null) { throw new SqlException(agent_.logWriter_, new ClientMessageId(SQLState.CLIENT_RESULT_SET_NOT_OPEN)); Modified: db/derby/code/trunk/java/testing/org/apache/derbyTesting/functionTests/master/derbyStress.out URL: http://svn.apache.org/viewvc/db/derby/code/trunk/java/testing/org/apache/derbyTesting/functionTests/master/derbyStress.out?rev=612262&r1=612261&r2=612262&view=diff ============================================================================== --- db/derby/code/trunk/java/testing/org/apache/derbyTesting/functionTests/master/derbyStress.out (original) +++ db/derby/code/trunk/java/testing/org/apache/derbyTesting/functionTests/master/derbyStress.out Tue Jan 15 14:36:38 2008 @@ -2,4 +2,5 @@ Testing with 2000 prepared statements PASS -- Prepared statement test DERBY-557: reExecuteStatementTest() PASSED -Test derbyStress finished. \ No newline at end of file +DERBY-3316: Multiple statement executions +Test derbyStress finished. Modified: db/derby/code/trunk/java/testing/org/apache/derbyTesting/functionTests/tests/jdbcapi/derbyStress.java URL: http://svn.apache.org/viewvc/db/derby/code/trunk/java/testing/org/apache/derbyTesting/functionTests/tests/jdbcapi/derbyStress.java?rev=612262&r1=612261&r2=612262&view=diff ============================================================================== --- db/derby/code/trunk/java/testing/org/apache/derbyTesting/functionTests/tests/jdbcapi/derbyStress.java (original) +++ db/derby/code/trunk/java/testing/org/apache/derbyTesting/functionTests/tests/jdbcapi/derbyStress.java Tue Jan 15 14:36:38 2008 @@ -54,7 +54,7 @@ } reExecuteStatementTest(); - + testDerby3316(); System.out.println("Test derbyStress finished."); } catch (SQLException se) { TestUtil.dumpSQLExceptions(se); @@ -133,4 +133,37 @@ conn.close(); System.out.println("PASSED"); } + + /** + * Test fix for leak if ResultSets are not closed. + * @throws Exception + */ + public static void testDerby3316() throws Exception { + System.out.println("DERBY-3316: Multiple statement executions "); + Connection conn = ij.startJBMS(); + + Statement s = conn.createStatement(); + s.executeUpdate("CREATE TABLE TAB (col1 varchar(32672))"); + PreparedStatement ps = conn.prepareStatement("INSERT INTO TAB VALUES(?)"); + ps.setString(1,"hello"); + ps.executeUpdate(); + ps.setString(1,"hello"); + ps.executeUpdate(); + ps.close(); + for (int i = 0; i < 2000; i++) + { + s = conn.createStatement(); + ResultSet rs = s.executeQuery("SELECT * from tab"); + // drain the resultset + while (rs.next()); + // With DERBY-3316, If I don't explicitly close the resultset or + // statement, we get a leak. + //rs.close(); + //s.close(); + } + s = conn.createStatement(); + s.executeUpdate("DROP TABLE TAB"); + s.close(); + } + }