如果我有三列的表,甲骨文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) –