简体   繁体   中英

Java, JDBC: Does closing a PreparedStatement also free up its memory footprint in the database connection?

As I understand it, each time a PreparedStatement is initialized, the statement gets cached in the memory allocated for the database connection. Therefore, if one initializes excessive PreparedStatement variables there is a risk of overflowing the memory available to the connection.

  1. Is the cached memory freed by calling close() on the PreparedStatement instances?

  2. Do two PreparedStatement containing identical SQL create duplicate caching events, or is the database smart enough not to cached a new instance of a duplicate PreparedStatement ?

Example 1, would this overflow connection memory?:

while (true) {
    PreparedStatement ps = connection.prepareStatement("SELECT id + ? FROM tbl");
    ps.setDouble(1, Math.random());
    ps.executeQuery();
    ps.close();
}

If it would, then what about this?:

while (true) {
    PreparedStatement ps = connection.prepareStatement("SELECT id FROM tbl");
    ps.executeQuery();
    ps.close();
}

Answer to both: That entirely depends on the JDBC driver.

Eg for PostgreSQL JDBC driver, see Server Prepared Statements :

The driver uses server side prepared statements by default when PreparedStatement API is used. In order to get to server-side prepare, you need to execute the query 5 times (that can be configured via prepareThreshold connection property). An internal counter keeps track of how many times the statement has been executed and when it reaches the threshold it will start to use server side prepared statements.

It is generally a good idea to reuse the same PreparedStatement object for performance reasons, however the driver is able to server-prepare statements automatically across connection.prepareStatement(...) calls.

[...]

Server-prepared statements consume memory both on the client and the server, so pgjdbc limits the number of server-prepared statements per connection. It can be configured via preparedStatementCacheQueries (default 256 , the number of queries known to pgjdbc), and preparedStatementCacheSizeMiB (default 5 , that is the client side cache size in megabytes per connection). Only a subset of statement cache is server-prepared as some of the statements might fail to reach prepareThreshold .

For MS SQL Server JDBC driver, see Prepared Statement Metadata Caching for the JDBC Driver .

For MySQL JDBC driver, see answer to Prepared Statement Cache with MySQL & JDBC .

I don't see any such feature for Oracle JDBC driver.

1> Not all drivers support precompilation. 2> Both JDBC and Database will perform cache eviction when necessary.

Example for Oracle JDBC driver:

Source: https://docs.oracle.com/cd/B28359_01/java.111/b31224/stmtcach.htm

Statements are removed from the cache to conform to the maximum size using a Least Recently Used (LRU) algorithm.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM