【问题标题】:Connection close连接关闭
【发布时间】:2018-06-15 07:14:31
【问题描述】:

有一个方法 getConnection() 来初始化一个连接。我知道,我可以使用

try (Connection conn = getConnection()) {
    ...
    Target t = new Target(conn);
    ...
}

在 Java 7 中使用该连接并在尝试结束时自动关闭它。但是如果我不尝试就直接使用下面的代码会发生什么:

Target t = new Target(getConnection());

这是否会造成资源泄漏,因为我无法关闭连接,因为我没有用于连接的变量?

【问题讨论】:

  • 是的,正是你所说的。
  • Connection 传递给Target 的实例即使关闭连接也可能会造成内存泄漏,具体取决于Target 的作用及其存在时间。

标签: java jdbc connection


【解决方案1】:

如果您使用没有 try-with-resources 的代码(或带有显式关闭的老式 try-finally),那么 - 显然 - 显示的代码不会关闭连接。因此,除非Target 以某种方式关闭连接,否则在这种情况下您将发生资源泄漏。

请注意,即使在使用 try-with-resources 时,即使连接关闭,您仍可能会出现内存泄漏。如果连接保存在 Target 的实例字段中,并且目标的寿命比 try-with-resources 块长,则可能会发生这种情况,因为在这种情况下,连接(以及连接持有的任何其他对象)不能被垃圾收集器,直到目标本身符合垃圾收集条件。

作为资源管理的一般经验法则,创建资源的人也负责关闭该资源(除非另有明确说明),因此除非您有充分的理由不这样做,否则您应该使用 try-with-资源在这里。

【讨论】:

  • 这里只需要澄清一下第二段。泄漏将只是 GC 无法获取的剩余参考,对吧?
  • @AxelH 是的,但根据所涉及的 JDBC 驱动程序,可能涉及更多(引用和来自连接的其他字段)
  • 目标不能在try-with-resources块之外被引用,我认为它会被GC破坏。您的意思是我应该为 Target 实现 java.lang.AutoCloseable 并在自动关闭期间将 Target 的连接实例变量设置为 null 吗?
  • @Andre 如果Target 没有超出不必要的try-with-resources,它将被GC回收。
  • 是的,通过引用,我的意思是与它相关的所有内容。我当时正确理解你的观点。
【解决方案2】:

是的,你是对的,它会造成资源泄漏。 Java 中的 Connection 接口扩展了 AutoCloseable 接口,该接口表示“不再需要时必须关闭的资源”。因此,您必须在代码中完成后显式关闭连接(或使用免费的资源尝试)。

请注意您在尝试使用您传递的资源块时的情况 目标 t = new Target(conn);内存泄漏不是连接泄漏的微小变化。

【讨论】: