在我早期的Java Web应用程序中,我会在每个请求结束时close
Connection
。我不会关闭ResultSet
或PreapredStatement
,因为它们会在Connection
关闭时自动关闭。
但是,我的一些应用程序必须在循环中创建许多PreparedStatement
。因此,如果我没有单独close
他们,我会在请求完成之前收到OutOfMemory
错误。似乎每个Connection
都会保留对其所有PreparedStatement
的引用。
当变量变得不可访问时(即子例程返回),我习惯于Perl自动清理语句($sth
)。如果我在致电$sth
时仍然可以访问$dbh->disconnect
,那么我必须致电$sth->finish
,但大多数时候我的脚本无法访问,而且这不是必需的。
我认为Java可以使用finalize
方法并可能使用WeakReference
为开发人员提供类似的便利。当所有引用都消失且对象不可访问时,将调用finalize
方法。 (使用弱引用除外)
这是自动关闭PreparedStatement
的合理解决方案吗?如果是这样,我计划创建包装函数以在我的应用程序中实现这种自动化。如果这不是一个合理的解决方案,请解释。
阻止MySQL-Java Connector(JDBC驱动程序)的设计人员在原始设计中包含此自动化的可能副作用是什么?
我能想到的唯一副作用是MySQL服务器本身的内存开销。但是,当PreparedStatement
仍然打开时,我不知道MySQL服务器是否有任何开销。 MySQL中是否存在任何内存开销?
答案 0 :(得分:0)
当JVM决定它需要时,finalize方法运行 - 当对象超出范围时,它可能会也可能不会运行。例如,它与C ++析构函数不同。您不需要在循环中创建PreparedStatements - 整点是它们已经“准备好”并且可以多次使用。这并不意味着它应该永远存在,但如果在你的例子中你需要循环某些东西,它应该被重用。
简而言之 - 永远不要指望敲定。如果你打开一些东西然后关闭它。如果可能的话,在新代码中使用AutoClosable接口,这样您就不必担心了。
答案 1 :(得分:0)
我以前用Perl自动清理语句
我可以想象两个原因:
Connection
可能与Driver
强烈引用。这可以由WeakReference
取代,但它不会做你需要的(见下文)。我认为Java可以使用
finalize
方法为开发人员提供类似的便利,并可能使用WeakReference
。
没办法。 GC只是回收内存的工具,滥用其他任何不起作用的工具(见下文)。
- 这是自动关闭
醇>PreparedStatement
的合理解决方案吗?
没有。它的所有优点都在于帮助您了解是否以及在何处泄漏资源,以便您可以解决问题。问题是其他资源可能会更快耗尽,留下大量内存,但是没有单一的免费文件描述符。因此,GC不会触发。您可以手动拨打System.gc
,但这会浪费很多时间。
- 阻止MySQL-Java Connector的设计者将这种自动化纳入其原始设计的可能副作用是什么?
醇>
它无法运作。如果有可能,那么它将在JDBC中实现,以便驱动程序作者不需要打扰。
- 我能想到的唯一副作用是MySQL服务器本身的内存开销。
醇>
我打赌,当MySQLConnection
关闭时,它会告诉服务器释放相关资源。有such resources。
我强烈建议您忘记使用GC。 Java中没有完美的解决方案,但有许多好的解决方案:
ResultSet
转换为List<Object[]>
。