在我早期的Java Web应用程序中,我将在每个请求结束时close Connection。我不会关闭ResultSetPreapredStatement,因为当Connection关闭时它们会自动关闭。

但是,我的某些应用程序必须在循环中创建许多PreparedStatement。因此,如果我没有单独close它们,则在请求完成之前会出现OutOfMemory错误。似乎每个Connection都保留对其所有PreparedStatement的引用。

我习惯于Perl在变量变得不可访问时(即子例程返回)自动清除语句($sth)。如果在调用$sth时仍可以访问$dbh->disconnect,则必须调用$sth->finish,但是大多数情况下,在脚本末尾无法访问finalize,这不是必需的。

我认为Java可以使用WeakReference方法并可能使用finalize为开发人员提供类似的便利。当所有引用都消失并且该对象不可访问时,将调用PreparedStatement方法。 (使用弱引用除外)


这是自动关闭PreparedStatement的合理解决方案吗?如果是这样,我计划创建包装函数以在我的应用程序中实现这种自动化。如果这不是一个合理的解决方案,请解释。
有什么可能的副作用导致MySQL-Java Connector(JDBC驱动程序)的设计者无法在其原始设计中包括这种自动化功能?
我唯一想到的副作用就是MySQL服务器本身的内存开销。但是,我不知道保持打开状态时,MySQL服务器是否还有任何开销。 MySQL中是否有任何保留内存的开销?

最佳答案

当JVM决定需要时,finalize方法将运行-当对象超出范围时,它可能运行也可能不运行。例如,它与C ++析构函数不同。您不需要在循环中创建PreparedStatement-整个要点是它们是“准备好的”并且可以多次使用。这并不意味着它应该永远存在,但是如果在您的示例中需要遍历某些内容,则应该重新使用它。

简而言之-永远不要指望完成。如果您打开某物,则将其关闭。如果可能的话,请在新代码中使用AutoClosable接口,这样您就不必担心它了。

10-07 19:22
查看更多