2016-08-03 54 views
0

如果我有三列的表,甲骨文JDBC内存分配而获取一个结果

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

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

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

感谢

+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个字节(= UTF-16中的20个字符)+ 22个字节+ 100个字节(= UTF-16中的100个字符)* 100.其中总共大约16kb(可能有一点更多)

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

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

您可以描绘获取大小,以分配在检索操作期间使用的缓冲区。类似于一个的BufferedInputStream

+0

我不知道Oracle JDBC驱动程序的内部实现,但没有必要提前预留内存:它也可以在收到对象时分配对象:因此不再接收行==没有分配额外的内存。 –

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

你可以下潜到:(启用准备语句缓存与否,参数,您可以通过-D选项传递的)http://www.oracle.com/technetwork/database/application-development/t-12c-1964666.pdf

正如你可以看到它的依赖的JDBC驱动程序,驱动程序配置的版本和许多许多其他因素。

它甚至依赖于你的应用程序中的其他SQL语句。

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

在最坏的情况下,你需要通过其他的SQL语句调用你已经在准备语句缓存已经(为Oracle JDBC < 11.2)