Memory leak in 7.0.3 JDBC driver - Mailing list pgsql-bugs

From Steve Sullivan
Subject Memory leak in 7.0.3 JDBC driver
Date
Msg-id 200106171759.f5HHxLA09947@localhost.localdomain
Whole thread Raw
Responses RE: Memory leak in 7.0.3 JDBC driver
List pgsql-bugs
Hi,

I'm running Postgresql 7.0.3 on Redhat 7.1 on a Pentium.
When I use Connection.getCatalog() and similar calls,
the amount of free memory slowly decreases.  I get:

after get catalog: 0:  totmem: 2031616 freemem: 1899480
after get catalog: 100:  totmem: 2031616 freemem: 1854576
after get catalog: 200:  totmem: 2031616 freemem: 1810008
after get catalog: 300:  totmem: 2031616 freemem: 1765104
after get catalog: 400:  totmem: 2031616 freemem: 1720200
after get catalog: 500:  totmem: 2031616 freemem: 1675296
after get catalog: 600:  totmem: 2031616 freemem: 1630808
after get catalog: 700:  totmem: 2031616 freemem: 1585904
after get catalog: 800:  totmem: 2031616 freemem: 1541000
after get catalog: 900:  totmem: 2031616 freemem: 1496096

It's losing about 448 bytes per iteration.
The Java test program I wrote is appended.  I invoked it using:

java Tbtestc org.postgresql.Driver jdbc:postgresql:mydb myuser mypswd testtablea > loga

If you need any further info, please contact me.
Thanks,

Steve

========================================
Steve Sullivan    sullivan@mathcom.com

   Mathcom Solutions, Inc.
    * Java, XML, and web oriented development.
    * Language development and translation.
    * Optimization, simulation, and mathematical modeling.

http://www.mathcom.com    303-494-7115
========================================



========== begin Tbtestc.java ==========

import java.io.PrintWriter;
import java.sql.Connection;
import java.sql.DatabaseMetaData;
import java.sql.DriverManager;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.ResultSetMetaData;
import java.sql.SQLException;
import java.sql.Statement;
import java.sql.Types;

/**
 * Tests simple jdbc access for memory leaks.
 */


public class Tbtestc {
    public static void main( String[] args) {
        new Tbtestc( args);
    }

    void prtln( String msg) {
        System.out.println( msg);
    }

    void badparms( String msg)
    {
        prtln("");
        prtln("Testc: Error: " + msg);
        prtln("args:  drivername url userid pswd tabname (will be deleted)");
        System.exit(1);
    }


    public Tbtestc( String[] args) {
        int ii;

        if (args.length != 5) badparms("wrong num parms");
        String drivername    = args[0];
        String url            = args[1];
        String userid        = args[2];
        String pswd            = args[3];
        String tabname        = args[4];

        // Connect to database and run the tests
        try {
            testit( drivername, url, userid, pswd, tabname);
        }
        catch( Exception exc) {
            prtln("Tbtestc: error: " + exc);
            exc.printStackTrace();
        }
    }


    void testit(
        String drivername,
        String url,
        String userid,
        String pswd,
        String tabname)
    throws SQLException, ClassNotFoundException
    {
        int iterlim = 1000;
        int iterdelta = 100;
        int ii, jj, kk;
        int ncols;
        String tstg;
        ResultSet rs = null;
        int maxcolwidth = 30;

        Connection dbcon = null;
        Statement dbst = null;

        // Load the driver
        Class.forName( drivername);

        prtln("Connecting to Database URL = " + url);
        dbcon = DriverManager.getConnection( url, userid, pswd);
        prtln("got dbcon.");
        dbst = dbcon.createStatement();
        prtln("got dbst.");

        try { dbst.executeUpdate("drop table " + tabname); }
        catch( SQLException sqe) {
            prtln("could not drop table " + tabname + ": " + sqe);
        }

        dbst.executeUpdate("create table " + tabname
            + " (colstg varchar(22) not null,"
            + " colint integer not null,"
            + " primary key (colstg, colint))");
        prtln("testit: created " + tabname);

        prtfreemem("before get catalog");
        String catalog = null;
        int isol = 0;
        boolean readonly = false;
        boolean autocommit = false;
        for (kk = 0; kk < iterlim; kk++) {
            catalog = dbcon.getCatalog();
            isol = dbcon.getTransactionIsolation();
            readonly = dbcon.isReadOnly();
            autocommit = dbcon.getAutoCommit();
            if (kk % iterdelta == 0) prtfreemem("after get catalog: " + kk);
        }
        prtfreemem("after get catalog");
        prtln("    catalog: " + catalog);
        prtln("    transaction isolation level: " + isol);
        prtln("    read only: " + readonly);
        prtln("    auto commit: " + autocommit);

        DatabaseMetaData dbm = null;
        for (kk = 0; kk < iterlim; kk++) {
            dbm = dbcon.getMetaData();
            if (kk % iterdelta == 0) prtfreemem("after get dbm: " + kk);
        }
        prtfreemem("after get dbm");
        String prodname = null;
        String version = null;
        String geturl = null;
        String getuser = null;
        for (kk = 0; kk < iterlim; kk++) {
            prodname = dbm.getDatabaseProductName();
            version = dbm.getDatabaseProductVersion();
            geturl = dbm.getURL();
            getuser = dbm.getUserName();
            if (kk % iterdelta == 0) prtfreemem("after get prodname: " + kk);
        }
        prtfreemem("after get prodname");
        prtln("database meta data:");
        prtln("    product name: " + prodname);
        prtln("    version: " + version);
        prtln("    URL: " + geturl);
        prtln("    user: " + getuser);

        for (kk = 0; kk < iterlim; kk++) {
            ResultSet keyrs = dbm.getPrimaryKeys(
                null, null,            // catalog, schema
                tabname);
            keyrs.close();
            if (kk % iterdelta == 0) prtfreemem("after get keys: " + kk);
        }
        prtfreemem("after get keys");

    }



    void prtfreemem( String msgparm) {
        Runtime runtime = Runtime.getRuntime();
        runtime.gc();
        long totmem = runtime.totalMemory();
        long freemem = runtime.freeMemory();
        String msg = msgparm + ": "
            + " totmem: " + totmem
            + " freemem: " + freemem;
        System.out.println( msg);
    }


} // end class Tbtestc


========== end Tbtestc.java ==========

pgsql-bugs by date:

Previous
From: Steve McClure
Date:
Subject: PostgreSQL problem
Next
From: Peter Eisentraut
Date:
Subject: Re: pg_ctl restart just appends to command line instead of regenerating original cmd