获取结果集时的Oracle JDBC内存分配

时间:2016-08-03 04:36:33

标签: oracle jdbc memory-management

如果我有一个包含三列的表,

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

在获取结果之前,Oracle JDBC驱动程序分配了多少内存?

如果fetch size设置为100,即使查询仅返回100,驱动程序是否会为所有10条记录分配内存?

由于

3 个答案:

答案 0 :(得分:2)

Oracle数据库JDBC驱动程序,12之前的版本:

驱动程序在执行查询之前为每列分配最大大小乘以fetchSize中的行数。

例如,对于VARCHAR(4000)列,它将分配fetchSize的8k字节。


版本12(及更高版本):

在执行查询之前,它在fetchSize中每行每列分配大约15个字节。执行后,版本12中的驱动程序仅分配存储实际行数据所需的数量。

因此,版本12驱动程序通常使用的内存比早期版本少得多。驱动程序。


您的示例

在您的示例中,VARCHAR(20)可以大到40个字节,NUMBER可以大到22个字节,VARCHAR(100)大到100个字节。将fetchSize设置为100后,较旧的驱动程序将分配(40 + 22 + 100) * 100 = 16k。版本12驱动程序将分配3 * 15 * 100 = 4.5k。我忽略了两个驱动程序的额外开销。

答案 1 :(得分:0)

Oracle驱动程序分配fechtsize * max. size of one row

在你的情况下,这将是40个字节(= UTF-16中的20个字符)+ 22个字节+ 100个字节(= UTF-16中的100个字符)* 100.这总共大约16kb(可能更多一点) )

这实际上是驱动程序的唯一选择:如果您请求驱动程序通过网络发送100行,则必须分配足够的内存才能在内存中保存这100行。这意味着它必须假设最坏的情况并保留每列的最大长度。

一旦从服务器接收到数据,一旦将其转换为适当的Java对象,它将只占用所需的内存。

您可以设置提取大小以分配在检索操作期间使用的缓冲区。与例如类似一个BufferedInputStream

答案 2 :(得分:0)

您可以深入了解:http://www.oracle.com/technetwork/database/application-development/t-12c-1964666.pdf

正如您所看到的,它取决于JDBC驱动程序的版本,驱动程序配置(是否启用了准备语句缓存,您通过-D选项传递的参数)以及许多其他因素。

它甚至取决于您的应用程序中的其他SQL语句。

在最好的情况下,驱动程序不会分配任何内存,只是重用以前调用相同或不同语句的缓冲区(当然,取决于许多因素)。

在最糟糕的情况下,您将通过您已准备语句缓存中的其他SQL语句调用(对于Oracle JDBC< 11.2)分配获取数据所需的内存量