One of test cases I have written recently has failed with OOM. It
actually tests some SELECT logic loading "heavy" records with large binary
objects (geometries). Investigation that I have done showed exactly the
described below case: prepared statements (every SELECT in my test
produces a bit different SQL query) are cached (Apache DBCP2 library is
used for connection pooling with an option *ds.setPoolPreparedStatements(true);
*) and they hold last result set - (field "lastResult" of Query class
that is extended by Select class).
The chain is:
JdbcPreparedStatement -> CommandInterface (CommandContainer) -> Prepared
(Select -> Query) -> LocalResult (Query#lastResult).
So, prepared statements caching is ON in connection pool,
OPTIMIZE_REUSE_RESULTS option has default value, lot of unique SQL queries
that leads to continuous caching of prepared statements with complete
result set hold in memory until connection is closed or prepared statements
are released from connection's cache. We do not know how PS caching is
configured in general way.
My conclusion is that cleaning of this internally cached result set is a
must after we know that logic around PS is complete and goes to the
cache. I understand why result set is cached within Query object. We
need clearly distinguish cases when last result is still needed and when
it's not needed anymore for sure.
I suppose PreparedStatement.clearParameters() is exactly the moment when
we can safely get rid of the "last result". This method is also called
by DBCP2 before PS goes to the cache.
Prepared class gets empty method that can be overrided by subclasses:
public void clearCachedResults(){
}
Query class overrides it:
@Override
public void clearCachedResults() {
closeLastResult();
lastResult = null;
}
CommandInterface gets a method as well:
public void clearCachedResults();
CommandContainer implements it as:
public void clearCachedResults(){
prepared.clearCachedResults();
}
and JdbcPreparedStatement has additional logic to call
command.clearCachedResults();
inside of its #clearParameters().
Last result is cleaned when it's not needed, changes are minimal, test
case now runs successfully, additional debugging prooves cleaning of
results and GC.
If an approach is accepted I can make change request in GIT. May be naming
of methods could be better, let's think.
Vitali.
--
You received this message because you are subscribed to the Google Groups "H2
Database" group.
To unsubscribe from this group and stop receiving emails from it, send an email
to [email protected].
To post to this group, send email to [email protected].
Visit this group at https://groups.google.com/group/h2-database.
For more options, visit https://groups.google.com/d/optout.