如果我有三列的表,甲骨文JDBC内存分配而获取一个结果
NAME (VARCHAR2 20), AGE (NUMBER), LOCATION (VARCHAR2 50)
多少内存Oracle JDBC驱动程序获取结果之前分配?
如果fetch size
设置为100
,即使查询只返回10
,驱动程序是否会为所有100
记录分配内存?
感谢
如果我有三列的表,甲骨文JDBC内存分配而获取一个结果
NAME (VARCHAR2 20), AGE (NUMBER), LOCATION (VARCHAR2 50)
多少内存Oracle JDBC驱动程序获取结果之前分配?
如果fetch size
设置为100
,即使查询只返回10
,驱动程序是否会为所有100
记录分配内存?
感谢
Oracle驱动程序分配fechtsize * max. size of one row
。在你的情况下,这将是40个字节(= UTF-16中的20个字符)+ 22个字节+ 100个字节(= UTF-16中的100个字符)* 100.其中总共大约16kb(可能有一点更多)
这实际上是驱动程序的唯一选择:如果您请求驱动程序通过网络发送100行,它将分配足够的内存以便能够在内存中保存这100行。这意味着它必须假定最坏的情况并为每列保留最大长度。
一旦从服务器接收到数据,一旦将数据转换为适当的Java对象,它将只占用尽可能多的内存。
您可以描绘获取大小,以分配在检索操作期间使用的缓冲区。类似于一个的BufferedInputStream
我不知道Oracle JDBC驱动程序的内部实现,但没有必要提前预留内存:它也可以在收到对象时分配对象:因此不再接收行==没有分配额外的内存。 –
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
。我忽略了两个驱动程序中的额外开销。
你可以下潜到:(启用准备语句缓存与否,参数,您可以通过-D选项传递的)http://www.oracle.com/technetwork/database/application-development/t-12c-1964666.pdf
正如你可以看到它的依赖的JDBC驱动程序,驱动程序配置的版本和许多许多其他因素。
它甚至依赖于你的应用程序中的其他SQL语句。
在最好的情况下,驱动程序不会分配任何内存,而只是重用之前调用相同或不同语句的缓冲区(当然取决于很多因素)。
在最坏的情况下,你需要通过其他的SQL语句调用你已经在准备语句缓存已经(为Oracle JDBC < 11.2)
[参见本(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) –