Skip site navigation (1) Skip section navigation (2)

Memory leak in 7.0.3 JDBC driver

From: pgsql-bugs(at)postgresql(dot)org
To: pgsql-bugs(at)postgresql(dot)org
Subject: Memory leak in 7.0.3 JDBC driver
Date: 2001-06-19 15:01:19
Message-ID: 200106191501.f5JF1JK38926@hub.org (view raw or flat)
Thread:
Lists: pgsql-bugs
Steve Sullivan (sullivan(at)mathcom(dot)com) reports a bug with a severity of 2
The lower the number the more severe it is.

Short Description
 Memory leak in 7.0.3 JDBC driver

Long Description
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.
==> This is fatal in long-running server applications. <==

Running the test code below, 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

Note that the free memory shown in the last column steadily
decreases. The Java test program I wrote is appended.  I invoked it using:

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

Thanks,
Steve



Sample Code
========== 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 ==========


No file was uploaded with this report


pgsql-bugs by date

Next:From: pgsql-bugsDate: 2001-06-19 19:38:21
Subject: pg_ctl restart just appends to command line instead of regenerating original cmd
Previous:From: Piotr KrukowieckiDate: 2001-06-18 19:59:35
Subject: psql (frontend) segfaults

Privacy Policy | About PostgreSQL
Copyright © 1996-2014 The PostgreSQL Global Development Group