Java, JDBC: освобождает ли закрытие PreparedStatement и его объем памяти в соединении с базой данных? - PullRequest
2 голосов
/ 07 июня 2019

Насколько я понимаю, каждый раз, когда PreparedStatement инициализируется, оператор кэшируется в памяти, выделенной для соединения с базой данных.Следовательно, если инициализировать избыточные переменные PreparedStatement, существует риск переполнения памяти, доступной для соединения.

  1. Освобождается ли кэшированная память путем вызова close() в PreparedStatement экземплярах?

  2. Выполнение двух PreparedStatement, содержащих идентичный SQL, создаетповторяющиеся события кэширования, или база данных достаточно умна, чтобы не кэшировать новый экземпляр дубликата PreparedStatement?

Пример 1, будет ли переполнение памяти соединения?:

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

Если так, то как насчет этого?:

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

Ответы [ 2 ]

0 голосов
/ 07 июня 2019

1> Не все драйверы поддерживают прекомпиляцию. 2> И JDBC, и База данных будут выполнять удаление кэша при необходимости.

Пример для драйвера Oracle JDBC:

Источник: https://docs.oracle.com/cd/B28359_01/java.111/b31224/stmtcach.htm

Заявления удаляются из кэша, чтобы соответствовать максимальному размеру с использованием алгоритма наименьшего числа недавно использовавшихся (LRU).

0 голосов
/ 07 июня 2019

Ответ на оба вопроса: это полностью зависит от драйвера JDBC.

например. для драйвера JDBC PostgreSQL см. Подготовленные сервером заявления :

Драйвер использует подготовленные операторы на стороне сервера по умолчанию при использовании PreparedStatement API. Чтобы приступить к подготовке на стороне сервера, необходимо выполнить запрос 5 раз (это можно настроить с помощью свойства prepareThreshold connection). Внутренний счетчик отслеживает, сколько раз оператор был выполнен, и когда он достигнет порогового значения, он начнет использовать подготовленные операторы на стороне сервера.

Как правило, для повышения производительности рекомендуется повторно использовать один и тот же объект PreparedStatement, однако драйвер может автоматически подготавливать операторы для операторов при вызовах connection.prepareStatement(...).

[...]

Подготовленные сервером операторы потребляют память как на клиенте, так и на сервере, поэтому pgjdbc ограничивает количество подготовленных сервером операторов на соединение. Его можно настроить с помощью preparedStatementCacheQueries (по умолчанию 256, количество запросов, известных pgjdbc) и preparedStatementCacheSizeMiB (по умолчанию 5, то есть размер кэша на стороне клиента в мегабайтах на соединение). Только подмножество statement cache подготовлено сервером, поскольку некоторые операторы могут не достичь prepareThreshold.

Для драйвера JDBC MS SQL Server см. Кэширование подготовленных метаданных операторов для драйвера JDBC .

Для драйвера JDBC MySQL см. Ответ на Кэш подготовленных операторов с MySQL & JDBC .

Я не вижу такой функции для драйвера Oracle JDBC.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...