Uploaded image for project: 'JDK'
  1. JDK
  2. JDK-4486684

Big Memory Leak in JdbcOdbcBridge with non-default ResultSets

XMLWordPrintable

    • Icon: Bug Bug
    • Resolution: Fixed
    • Icon: P3 P3
    • 1.4.0
    • 1.3.1
    • core-libs
    • rc1
    • x86
    • windows_2000



      Name: krC82822 Date: 07/31/2001


      java version "1.3.1"
      Java(TM) 2 Runtime Environment, Standard Edition (build 1.3.1-b24)
      Java HotSpot(TM) Client VM (build 1.3.1-b24, mixed mode)

      While profiling my application (using JProbe 3.0), I noticed that Int[] array
      objects were being leaked. I tracked this down to an allocation occurring in
      JdbcOdbcResultSet.setRowStatusPtr() - JdbcOdbcResultSet.java:4356

      The leak only occurs when calling createStatement() using non-default values
      for the ResultSet type (i.e. anything other than ResultSet.TYPE_FORWARD_ONLY
      and ResultSet.CONCUR_READ_ONLY).

      Each call to executeQuery() generates a new resultSet that leaks 1 Int[] object
      of 4 bytes. For an application making many, many queries the implications of
      this are horrific! One day's worth of leaks in my Application equate to
      0.5MBytes of memory when running at 1/100 of its expected capacity.

      I have experimated with the code listed below. Regardless of whether I re-use
      the Statement, or don't call 'close()' on the ResultSet the leak still occurs.

      Non-default ResultSet's because of MSSQLServer's BAD ODBC support for multiple
      active ResultSet's.

      Extract and tailor the following code to query any DB table using the bridge to
      reproduce the bug, not forgetting to use a profiler to see the leak.


      -------------------------Start of ResultSetBug.java
      import java.sql.*;
      public class ResultSetBug
      {
      public ResultSetBug()
      {
      DemonstrateTheBug();
      }
      static public void main(String[] args)
      {
      new ResultSetBug();
      }
      private void DemonstrateTheBug()
      {
      try
      {
      String dbDriver = "sun.jdbc.odbc.JdbcOdbcDriver";
      String dbUrl = "jdbc:odbc:<DSN>";
      String dbUser = "<User>";
      String dbPassword = "<Password>";

      Class.forName(dbDriver);
      Connection con = DriverManager.getConnection( dbUrl,

      dbUser,

      dbPassword);
      while(true)
      {
      for (int queryCount = 0; queryCount < 1000;
      queryCount++)
      {
      System.out.print("*");
      Statement s = con.createStatement(
      ResultSet.TYPE_SCROLL_INSENSITIVE,

      ResultSet.CONCUR_READ_ONLY );

      ResultSet rs = s.executeQuery( "select
      * from MyTable" );

      rs.close();
      s.close();
      rs = null;
      s = null;
      }

      Thread.sleep( 60000 );
      }
      }
      catch(java.lang.ClassNotFoundException cnfe)
      {
      System.out.println("Can't locate driver : " +
      cnfe.toString() );
      }
      catch(InterruptedException ie)
      {
      System.out.println("Interrupted : " + ie.toString() );
      }
      catch(SQLException se)
      {
      System.out.println("SQLException : " + se.toString() );
      }
      }
      }
      ---------------------------------------End of ResultSetBug.java
      (Review ID: 129150)
      ======================================================================

            jbrucesunw Jonathan Bruce (Inactive)
            kryansunw Kevin Ryan (Inactive)
            Votes:
            0 Vote for this issue
            Watchers:
            0 Start watching this issue

              Created:
              Updated:
              Resolved:
              Imported:
              Indexed: