Thread

  1. Memory leak in 7.0.3 JDBC driver

    Steve Sullivan <sullivan@mathcom.com> — 2001-06-17T17:59:21Z

    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 ==========
    
    
  2. RE: Memory leak in 7.0.3 JDBC driver

    Rainer Mager <rmager@vgkk.com> — 2001-06-20T23:21:32Z

    I posted yesterday regarding a memory leak I found in the JDBC driver in
    7.1. I didn't check but it is quite likely it also existed in 7.0. The patch
    I created hasn't been checked by anyone else yet so I don't know if it helps
    for others or not. Feel free to try it.
    
    --Rainer
    
    
    > -----Original Message-----
    > From: pgsql-bugs-owner@postgresql.org
    > [mailto:pgsql-bugs-owner@postgresql.org]On Behalf Of Steve Sullivan
    > Sent: Monday, June 18, 2001 2:59 AM
    > To: pgsql-bugs@postgresql.org
    > Subject: [BUGS] Memory leak in 7.0.3 JDBC driver
    >
    >
    >
    > 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 ==========
    >
    > ---------------------------(end of broadcast)---------------------------
    > TIP 4: Don't 'kill -9' the postmaster