2016-08-03 51 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)