[英]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.