Subject Re: Memory Leak in client-java - FIXED!
Author Roman Rokytskyy
Hi,

> We discovered that there were quite a few memory leaks in the last
> firebirdsql.jar that is available for download on the project
> website. Any isc_stmt_handle object was not garbage collected. But
> since then we got the latest version of the CVS repository and that
> leak seemed to be fixed. Could anyone confirm this?

This is a side effect of the other fix. Now each connection tracks
all statements it created and closes them when connection is closed.
Memory leaks are possible in managed scenario, when connection is
closed when there is no managed connection associated with it. But
I'm not sure if this can happen. I also want to check if we really
need to have references on all statement handles we allocate.

> But we still found another one. Whenever you execute a query and
> ask for the ResultSet it will not release the isc_tr_handle. See
> the following heap dump after 6000 execute statements:
>
> ... (skipped)
>
> You can see the 6000 isc_tr_handle_impl objects being retained. I
> debugged the source code and found the problem. It is located in the
> org.firebirdsql.jca.FBManagedConnectionFactory.java class. It
> stores a reference to the transaction when a statement returns a
> ResultSet in registerStatementWithTransaction(). The list used is
> static. The leak is that this reference is never removed. Below is
> the fix - basically a single line of code - that removes the
> transaction reference when the resultsets are discarded:
>
> private void forgetResultSets(isc_tr_handle tr) {
> //shouldn't need synchronization, only called by rollback
> and commit- then we're done
> //transaction/thread should also help.
> ArrayList stmts = (ArrayList)TransactionStatementMap.get
> (tr);
> if (stmts != null) {
> Iterator i = stmts.iterator();
> while (i.hasNext()) {
> ((FBStatement)i.next()).forgetResultSet();
> }
> stmts.clear();
> }
> // lars 2002-10-24: Fix memory leak - release transaction
> from static list
> TransactionStatementMap.remove(tr);
> }
>
> Since it is private and used only in two spots (commit and
> rollback) it seems the best fit to implement the fix. Could someone
> do a code review on this and check the fix into CVS please?

Yes, this is in my todo list before the RC2 is released.

Best regards,
Roman Rokytskyy