在我早期的Java Web应用程序中,我将在每个请求结束时close
Connection
。我不会关闭ResultSet
或PreapredStatement
,因为当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接口,这样您就不必担心它了。