繁体   English   中英

Java,JDBC:关闭PreparedStatement是否还会释放其在数据库连接中的内存空间?

[英]Java, JDBC: Does closing a PreparedStatement also free up its memory footprint in the database connection?

据我了解,每次PreparedStatement初始化时,该语句都会缓存在为数据库连接分配的内存中。 因此,如果初始化过多的PreparedStatement变量,则存在溢出连接可用内存的风险。

  1. 通过在PreparedStatement实例上调用close()释放缓存的内存吗?

  2. 是两个包含相同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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM