2016-08-03 4 views
0

Если у меня есть таблица с тремя столбцами,Oracle JDBC распределения памяти при выборке результирующего

NAME (VARCHAR2 20), AGE (NUMBER), LOCATION (VARCHAR2 50) 

как объем памяти драйвер Oracle JDBC выделить перед получением результата?

Если fetch size установлен в 100, делает драйвер выделяет память для всех 100 записей, даже если запрос возвращает только 10?

Благодаря

+0

[Смотреть это] (HTTP: //stackoverflow.com/questions/8234087/where-result-set-is-stored-while-working-with-jdbc-and-oracle-driver). Насколько я знаю, выделенная память в куче Java никогда бы не превышала фактического количества строк. [См. Также этот раздел] (http://stackoverflow.com/questions/6651250/resultset-memory) –

ответ

0

Драйвер Oracle выделяет fechtsize * max. size of one row.

В вашем случае это будет 40 байт (= 20 символов в UTF-16) + 22 байта + 100 байт (= 100 символов в UTF-16) * 100. Это дает примерно 16 килобайт (возможно, немного больше)

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

После получения данных с сервера потребуется только столько памяти, сколько требуется, как только оно будет преобразовано в соответствующие объекты Java.

Вы можете представить размер выборки, чтобы выделить буфер , который используется во время операций поиска. Аналогично, например, водитель BufferedInputStream

+0

Я не участвую в внутренней реализации драйвера JDBC Oracle, но нет необходимости резервировать память заранее: он также может выделять объекты по мере их получения: так что больше не принимается строк == не выделяется дополнительная память. –

1

база данных Oracle JDBC, версиях до 12:

Драйвер выделяет максимальный размер для каждого столбца раза количество строк в fetchSize перед выполнением запроса.

Например, для столбца VARCHAR(4000) он выделяет 8k байтов в fetchSize.


версии 12 (и выше):

он выделяет примерно 15 байт в колонке на строку в fetchSize перед выполнением запроса. После выполнения драйвера в версии 12 выделяется столько, сколько необходимо для хранения фактических данных строки.

В результате драйверы версии 12 обычно используют значительно меньше памяти, чем драйверы более ранних версий.


Ваш пример:

В вашем например VARCHAR(20) может быть столь же большой, как 40 байтов, NUMBER может быть как 22 байт и VARCHAR(100), как большой, как 100 байт. С fetchSize, установленным в 100 старших драйверов, будет выделено (40 + 22 + 100) * 100 = 16k. Драйвер версии 12 выделил 3 * 15 * 100 = 4.5k.В обоих драйверах есть дополнительные накладные расходы, которые я игнорирую.

0

Вы можете погрузиться в: http://www.oracle.com/technetwork/database/application-development/t-12c-1964666.pdf

Как вы можете видеть, что это зависит от версии драйвера JDBC, конфигурации драйвера (включен в Приготовьте себе кэш или нет, параметр, принятый опцией -D) и многие многие другие факторы ,

Это зависит даже от других операторов SQL, которые у вас есть в приложении.

В лучшем случае Драйвер не выделяет какую-либо память, а просто повторно использует буферы из предыдущего вызова того же или другого оператора (в зависимости от многих факторов).

В худшем случае будет выделять столько объем памяти, сколько нужно для получения данных по другой SQL Statement вызова, что вы в Приготовьте себе кэш уже (для Oracle JDBC < 11,2)

Смежные вопросы