Details
-
Type:
Bug
-
Status:
Closed
-
Priority:
Trivial
-
Resolution: Fixed
-
Affects Version/s: 1.3.3
-
Fix Version/s: 2.0.0
-
Labels:None
-
Environment:Hibernate3.5, SQLServer
-
Number of attachments :
Description
I face a memory retention problem with JdbcPooledConnection uncachedStatements list.
Problem is that this list keeps hard references to Statements even after they had been closed by the user.
The list is only cleared when releasing the connection back to the pool.
On long transaction with many queries this may lead to a serious memory consumption problems.
My scenario:
During a single transaction I perform many queries.
After 9653 queries I create a dump and analyzing it with SAPMemoryAnalyzer and JHAT I saw following:
-115MB of total 133MB are used by the 9653 SQLServerPreparedStatements
-making some spot test I see that all SQLServerPreparedStatements are already closed
-the unique referrer to this SQLServerPreparedStatements is the JdbcPooledConnection uncachedStatements list
Workaround: setting PreparedStatementCacheSize to a value > 0 resolved the problem to me,
(but I assume that it doesn't work for all scenarios)
---------------------------------------------------------------------------------------------
First answer by Ludovic:
Keeping a list of all opened statements is required for compliance with JDBC spec which says if a connection gets closed all associated resources should be closed as well. Another workaround would be to close the connection and open another one from time to time in your transaction.
Ludovic and Guenther,
After thinking about this a bit, I don't think we should track uncached statements. Our connection should be almost completely transparent to the user. The underlying driver connection (be it Derby, MySQL, Oracle, etc.) is required by the spec. to track statements and close associated resources when the connection closes – it is not our responsibility to do so. If the user obtains a statement (uncached) from our connection, we are essentially a pass-thru to the underlying connection. If the user closes that statement and releases their reference to it, BTM shouldn't care one way or another.
If the user elects to use connection pooling, their expectation should be that the connection itself may not be closed for an indeterminate period of time, and therefore they are responsible for the closing of statements.
However, if we do wish to track uncached statements, those statements should be wrapped in a proxy such that when they are closed explicitly by the user they are removed from our tracking list. Doing so allows resources, including ResultSets, to be freed and garbage collected in a timely manner. In this case, our tracking list wouldn't be a list of uncached statements, but rather a list of "un-closed uncached" statements.
"Un-closed uncached" statements would be closed explicitly when our connection closes or is returned to the pool.