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