postgresql-jdbc.git / summary / log / commit / refs

commit    0bef49279d0c4d5bbb58e4ced79eff1f6d16d4c6
Author:   Kris Jurka <books@ejurka.com>
Date:     Wed Nov 23 19:24:55 2005 +0000

    Add a URL parameter to enable logging of Connections which are
    finalized, but not closed.  This will help people debug leaks.


doc/pgjdbc.xml | 22 +++++++++++++++++++++- org/postgresql/Driver.java.in | 4 +++- org/postgresql/jdbc2/AbstractJdbc2Connection.java | 18 +++++++++++++++++- 3 files changed, 41 insertions(+), 3 deletions(-) diff --git a/doc/pgjdbc.xml b/doc/pgjdbc.xml index 8a8970a5..17065fc8 100644 --- a/doc/pgjdbc.xml +++ b/doc/pgjdbc.xml @@ -1,7 +1,7 @@ <?xml version="1.0"?> <!-- Copyright (c) 2004-2005, PostgreSQL Global Development Group - $PostgreSQL: pgjdbc/doc/pgjdbc.xml,v 1.24 2005/03/04 07:10:13 jurka Exp $ + $PostgreSQL: pgjdbc/doc/pgjdbc.xml,v 1.25 2005/04/10 15:15:05 jurka Exp $ --> <!DOCTYPE book PUBLIC "-//OASIS//DTD DocBook XML V4.2//EN" "http://www.oasis-open.org/docbook/xml/4.2/docbookx.dtd"> @@ -540,6 +540,26 @@ Connection conn = DriverManager.getConnection(url); </listitem> </varlistentry> + <varlistentry> + <term><varname>logUnclosedConnections</varname> = <type>boolean</type></term> + <listitem> + <para> + Clients may leak <classname>Connection</classname> objects by + failing to call its <function>close()</function> method. + Eventually these objects will be garbage collected and the + <function>finalize()</function> method will be called which will + close the <classname>Connection</classname> if caller has + neglected to do this himself. The usage of a finalizer is just + a stopgap solution. To help developers detect and correct the + source of these leaks the <literal>logUnclosedConnections</literal> + <acronym>URL</acronym> parameter has been added. It captures + a stacktrace at each <classname>Connection</classname> opening + and if the <function>finalize()</function> method is reached without + having been closed the stacktrace is printed to the log. + </para> + </listitem> + </varlistentry> + <varlistentry> <term><varname>prepareThreshold</varname> = <type>int</type></term> <listitem> diff --git a/org/postgresql/Driver.java.in b/org/postgresql/Driver.java.in index b545d58d..3b38a8ad 100644 --- a/org/postgresql/Driver.java.in +++ b/org/postgresql/Driver.java.in @@ -3,7 +3,7 @@ * Copyright (c) 2003-2005, PostgreSQL Global Development Group * * IDENTIFICATION -* $PostgreSQL: pgjdbc/org/postgresql/Driver.java.in,v 1.64 2005/02/02 23:30:30 oliver Exp $ +* $PostgreSQL: pgjdbc/org/postgresql/Driver.java.in,v 1.65 2005/02/15 08:56:24 jurka Exp $ * *------------------------------------------------------------------------- */ @@ -414,6 +414,8 @@ public class Driver implements java.sql.Driver new String[] { "0", "1", "2" } }, { "allowEncodingChanges", Boolean.FALSE, "Allow the user to change the client_encoding variable." }, + { "logUnclosedConnections", Boolean.FALSE, + "When connections that are not explicitly closed are garbage collected, log the stacktrace from the opening of the connection to trace the leak source."}, { "prepareThreshold", Boolean.FALSE, "Default statement prepare threshold (numeric)." }, { "charSet", Boolean.FALSE, diff --git a/org/postgresql/jdbc2/AbstractJdbc2Connection.java b/org/postgresql/jdbc2/AbstractJdbc2Connection.java index 1a436b98..2e0ad685 100644 --- a/org/postgresql/jdbc2/AbstractJdbc2Connection.java +++ b/org/postgresql/jdbc2/AbstractJdbc2Connection.java @@ -3,7 +3,7 @@ * Copyright (c) 2004-2005, PostgreSQL Global Development Group * * IDENTIFICATION -* $PostgreSQL: pgjdbc/org/postgresql/jdbc2/AbstractJdbc2Connection.java,v 1.31 2005/07/04 18:50:29 davec Exp $ +* $PostgreSQL: pgjdbc/org/postgresql/jdbc2/AbstractJdbc2Connection.java,v 1.32 2005/08/01 06:54:14 oliver Exp $ * *------------------------------------------------------------------------- */ @@ -37,6 +37,8 @@ public abstract class AbstractJdbc2Connection implements BaseConnection /* URL we were created via */ private final String creatingURL; + private final String openStackTrace; + /* Actual network handler */ private final ProtocolConnection protoConnection; /* Compatibility version */ @@ -134,6 +136,16 @@ public abstract class AbstractJdbc2Connection implements BaseConnection // Initialize object handling _typeCache = new TypeInfoCache(this); initObjectTypes(info); + + if (Boolean.parseBoolean(info.getProperty("logUnclosedConnections"))) { + java.io.CharArrayWriter caw = new java.io.CharArrayWriter(1024); + Exception e = new Exception(); + e.printStackTrace(new java.io.PrintWriter(caw)); + openStackTrace = caw.toString(); + enableDriverManagerLogging(); + } else { + openStackTrace = null; + } } private final TimestampUtils timestampUtils; @@ -795,6 +807,10 @@ public abstract class AbstractJdbc2Connection implements BaseConnection */ public void finalize() throws Throwable { + if (openStackTrace != null && !isClosed()) { + DriverManager.println(GT.tr("Finalizing a Connection that was never closed. Connection was opened here:")); + DriverManager.println(openStackTrace); + } close(); } [parent: cb7113314937]