[英]Java, JDBC: Does closing a PreparedStatement also free up its memory footprint in the database connection?
據我了解,每次PreparedStatement
初始化時,該語句都會緩存在為數據庫連接分配的內存中。 因此,如果初始化過多的PreparedStatement
變量,則存在溢出連接可用內存的風險。
通過在PreparedStatement
實例上調用close()
釋放緩存的內存嗎?
是兩個包含相同SQL的PreparedStatement
創建重復的緩存事件,還是數據庫足夠聰明以至於不緩存重復的PreparedStatement
的新實例?
示例1,此連接存儲器是否溢出?:
while (true) {
PreparedStatement ps = connection.prepareStatement("SELECT id + ? FROM tbl");
ps.setDouble(1, Math.random());
ps.executeQuery();
ps.close();
}
如果可以,那么呢?:
while (true) {
PreparedStatement ps = connection.prepareStatement("SELECT id FROM tbl");
ps.executeQuery();
ps.close();
}
兩者的答案:這完全取決於JDBC驅動程序。
例如,對於PostgreSQL JDBC驅動程序,請參閱服務器准備的語句 :
當使用
PreparedStatement
API時,驅動程序默認使用服務器端的預處理語句。 為了進行服務器端的准備,您需要執行5次查詢(可以通過prepareThreshold
連接屬性進行配置)。 內部計數器跟蹤該語句已執行了多少次,以及何時達到閾值,它將開始使用服務器端准備好的語句。出於性能原因,重用相同的
PreparedStatement
對象通常是一個好主意,但是驅動程序能夠跨connection.prepareStatement(...)
調用自動對服務器進行語句准備。[...]
服務器准備的語句消耗客戶端和服務器上的內存,因此pgjdbc限制了每個連接中服務器准備的語句的數量。 它可以通過被配置
preparedStatementCacheQueries
(默認256
,已知pgjdbc查詢的數量),和preparedStatementCacheSizeMiB
(默認5
,也就是在每個連接兆字節客戶端緩存大小)。 只有部分statement cache
是服務器准備的,因為某些語句可能無法達到prepareThreshold
。
對於MS SQL Server JDBC驅動程序,請參閱JDBC驅動程序的預處理語句元數據緩存 。
對於MySQL JDBC驅動程序,請參見“使用MySQL&JDBC准備語句緩存”的答案。
我沒有看到針對Oracle JDBC驅動程序的任何此類功能。
1>並非所有驅動程序都支持預編譯。 2>必要時,JDBC和數據庫都將執行緩存驅逐。
Oracle JDBC驅動程序示例:
資料來源: https : //docs.oracle.com/cd/B28359_01/java.111/b31224/stmtcach.htm
使用最近最少使用(LRU)算法從高速緩存中刪除語句以使其符合最大大小。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.