当前位置: 首页 > 知识库问答 >
问题:

Java,JDBC:是否关闭准备语句也会释放其在数据库连接中的内存占用?

梁渊
2023-03-14

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

>

  • 是否通过调用PreparedStatement实例来释放缓存内存?

    是否有两个包含相同的SQL的准备声明创建重复的缓存事件,或者数据库是否足够智能,不会缓存重复的准备声明的新实例?

    示例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();
    }
    
  • 共有2个答案

    季骏祥
    2023-03-14
    1. 并非所有驱动程序都支持预编译。
    2. JDBC和Database都会在必要时执行缓存驱逐。

    Oracle JDBC驱动程序示例:

    资料来源:https://docs.oracle.com/cd/B28359_01/java.111/b31224/stmtcach.htm

    使用最近最少使用(LRU)算法从缓存中删除语句,以符合最大大小。

    程树
    2023-03-14

    两者的答案都是:这完全取决于JDBC驱动程序。

    E、 g.关于PostgreSQL JDBC驱动程序,请参阅服务器准备的语句:

    当使用API时,驱动程序默认使用服务器端准备的语句。为了进入服务器端准备,您需要执行查询5次(可以通过连接属性配置)。内部计数器跟踪语句执行了多少次,当达到阈值时,它将开始使用服务器端准备的语句。

    出于性能原因,通常最好重用相同的PreparedStatement对象,但是驱动程序能够跨连接自动为PreparedStatement提供服务器。prepareStatement(…)调用

    [...]

    服务器准备的语句消耗客户端和服务器上的内存,因此pgjdbc限制了每个连接中服务器准备的语句的数量。可以通过preparedStatementCacheQueries(默认值为256,pgjdbc已知的查询数)和PreparedStatementCacheSizeMB(默认值为5,即每个连接的客户端缓存大小,单位为MB)进行配置。服务器只准备了语句缓存的一个子集,因为一些语句可能无法到达prepareThreshold。

    有关MSSQLServer JDBC驱动程序,请参阅JDBC驱动程序的已准备语句元数据缓存。

    对于MySQL JDBC驱动程序,请参阅MySQL对准备语句缓存的回答

    我没有看到Oracle JDBC驱动程序的任何此类功能。

     类似资料:
    • 我正在为我的sqlite日志数据库使用准备好的语句。 我的线程每50ms运行一次,将日志缓冲区中的内容写入数据库。 目前,我正在对每个线程运行一个新的准备好的语句批处理,并在所有数据线写入后关闭它们。 现在我想知道是否最好将准备好的语句保存在内存中,并仅在线程关闭/中断时关闭它? 我之所以进行这种预优化,是因为我希望这个日志线程对主应用程序性能的干扰尽可能小,我可以想象每50秒分配/解析/验证资源

    • 但是,我不能让它在JDBC驱动程序上作为一个准备好的语句工作。id的值应该是一个参数,因此我尝试将其作为传递给: 在这里,当我尝试设置参数时,我得到了以下异常: 当我尝试以下任一操作时,参数设置正确:

    • 这是我目前的代码。我有几个问题: 数据库正忙-错误 SQL错误或缺少数据库 结果集已关闭 如果我想防止这两个错误,我应该使用哪种代码结构?我需要在try块中连接吗?我需要在哪里关闭连接?我需要在哪里关闭准备语句? 直到现在,我还无法通过自己连接不同页面的信息来找到解决方案。

    • 我读过很多帖子,人们说在java、语句等中关闭连接,但我没有找到我的问题的答案。 我问我不做Con.close(),但我做所以它会关闭连接或不? 所以我只想知道,当我们关闭结果集时,连接是否会关闭?

    • 问题内容: 我知道有些人可能会回答这个问题,但是我的问题来自于您和您的答案。我正在阅读有关SQL注入以及如何保护数据库的过去两个小时的问答。我看到的大量网页和教程也是如此。 我发现有一半人声称prepare语句确实可以保护您的数据库,而另外50人则声称不是。 另一方面,我读到mysql_real_escape_string可以完成这项工作,而其他人则说不行。 我的问题是谁相信? 另外,这是适当的准

    • 我可能有一个简单的编码问题,但我无法解决。我在MySQL数据库中有英文或中文的地址,所以我使用了utf8_unicode_ci。我从数据库中检索我的汉字没有问题,但我不能在准备好的请求中使用汉字。 我解释说:如果我打 我会得到一个结果,因为其中一个地址包含“”但如果我尝试使用一个准备好的请求: 如果$_post[“address”]在英文中有效,在中文中就不行了:p 编辑: 当请求show变量时,