Thread: AbstractJdbc2ResultSet.FAST_NUMBER_FAILED brings class loader leak

AbstractJdbc2ResultSet.FAST_NUMBER_FAILED brings class loader leak

From
Kohei Nozaki
Date:
Hello, I'm working on fixing the issue "java.lang.OutOfMemoryError:
Metaspace" in the time of redeploy where running an web application on
Tomcat.

I have acquired a heap dump and found a weird Root GC reference which is
connected to org.postgresql.jdbc2.AbstractJdbc2ResultSet. The heap dump
shows that it saves a (intentionally constructed) NumberFormatException
in a private static final field FAST_NUMBER_FAILED and that field has
backtrace field which references a Servlet class that loaded by
WebappClassLoader.

Here's a screenshot of Eclipse Memory Analyzer:
http://www.nailedtothex.org/roller/kyle/mediaresource/2fabd2a0-10a3-4d45-b8c8-589763d15824

I think AbstractJdbc2ResultSet should stop saving a intentionally
constructed Exception in a static field because it creates a strong
reference to a class which invoked the database operation at the first
time regardless if it's loaded by WebappClassLoader. It will be a cause
of class loader leak.

[Steps to reproduce]

1. Put postgresql-9.3-1100.jdbc41.jar to $TOMCAT_HOME/lib
2. Put following element to $TOMCAT_HOME/conf/context.xml

    <Resource name="jdbc/PostgreSQLDS"
              url="jdbc:postgresql://localhost:5432/somedb"
              driverClassName="org.postgresql.Driver"
              username="postgres"
              password="***"
              auth="Container"
              type="javax.sql.DataSource"
              maxActive="20"
              maxIdle="5"
              maxWait="10000"/>

3. git clone https://github.com/lbtc-xxx/jdbc-servlet
4. cd jdbc-servlet; mvn clean package
5. deploy the WAR
6. visit http://localhost:8080/jdbc-servlet-1.0-SNAPSHOT
7. undeploy and deploy the WAR several times (keep your JVM running)
8. acquire heap dump and load it with Eclipse Memory Analyzer

[My environment]

* postgresql-9.3-1100.jdbc41.jar
* Tomcat 8.0.18
* Oracle JDK 8u60
* PostgreSQL 9.3.4

Thanks.


Re: AbstractJdbc2ResultSet.FAST_NUMBER_FAILED brings class loader leak

From
Dave Cramer
Date:
This is a fairly old version of the 9.3 driver. That being said you can use the 9.4 driver which is substantially different.

I have recently updated a 9.3 driver for a bug, but would prefer any changes occur on the 9.4 driver


On 12 October 2015 at 07:46, Kohei Nozaki <kyle@nailedtothex.org> wrote:
Hello, I'm working on fixing the issue "java.lang.OutOfMemoryError:
Metaspace" in the time of redeploy where running an web application on
Tomcat.

I have acquired a heap dump and found a weird Root GC reference which is
connected to org.postgresql.jdbc2.AbstractJdbc2ResultSet. The heap dump
shows that it saves a (intentionally constructed) NumberFormatException
in a private static final field FAST_NUMBER_FAILED and that field has
backtrace field which references a Servlet class that loaded by
WebappClassLoader.

Here's a screenshot of Eclipse Memory Analyzer:
http://www.nailedtothex.org/roller/kyle/mediaresource/2fabd2a0-10a3-4d45-b8c8-589763d15824

I think AbstractJdbc2ResultSet should stop saving a intentionally
constructed Exception in a static field because it creates a strong
reference to a class which invoked the database operation at the first
time regardless if it's loaded by WebappClassLoader. It will be a cause
of class loader leak.

[Steps to reproduce]

1. Put postgresql-9.3-1100.jdbc41.jar to $TOMCAT_HOME/lib
2. Put following element to $TOMCAT_HOME/conf/context.xml

    <Resource name="jdbc/PostgreSQLDS"
              url="jdbc:postgresql://localhost:5432/somedb"
              driverClassName="org.postgresql.Driver"
              username="postgres"
              password="***"
              auth="Container"
              type="javax.sql.DataSource"
              maxActive="20"
              maxIdle="5"
              maxWait="10000"/>

3. git clone https://github.com/lbtc-xxx/jdbc-servlet
4. cd jdbc-servlet; mvn clean package
5. deploy the WAR
6. visit http://localhost:8080/jdbc-servlet-1.0-SNAPSHOT
7. undeploy and deploy the WAR several times (keep your JVM running)
8. acquire heap dump and load it with Eclipse Memory Analyzer

[My environment]

* postgresql-9.3-1100.jdbc41.jar
* Tomcat 8.0.18
* Oracle JDK 8u60
* PostgreSQL 9.3.4

Thanks.


--
Sent via pgsql-jdbc mailing list (pgsql-jdbc@postgresql.org)
To make changes to your subscription:
http://www.postgresql.org/mailpref/pgsql-jdbc

Re: AbstractJdbc2ResultSet.FAST_NUMBER_FAILED brings class loader leak

From
Vladimir Sitnikov
Date:
Kohei,

Thanks for the detailed testcase.

I've filed a pull request to fix the problem:
https://github.com/pgjdbc/pgjdbc/pull/397


Vladimir


Re: AbstractJdbc2ResultSet.FAST_NUMBER_FAILED brings class loader leak

From
Kohei Nozaki
Date:
Hi Vladimir,

Thank you for the fix, I've just confirmed that the class loader leak
has been fixed. Now all of the WebappClassLoaders are garbage collected
cleanly.

Regards,
Kohei

On 10/13/15 0:58, Vladimir Sitnikov wrote:
> Kohei,
>
> Thanks for the detailed testcase.
>
> I've filed a pull request to fix the problem:
> https://github.com/pgjdbc/pgjdbc/pull/397
>
>
> Vladimir
>
>