我正在使用Sun JVM在Glassfish上运行应用程序。我们的一位开发人员进行了无害的改变,似乎对系统造成了严重破坏。他所做的只是将现有的工厂方法调用与另一个进行包装以提供一些日志记录,如下所示:
// Old code
PreparedStatement stmt = connection.prepareStatement(sql);
// New code
PreparedStatement stmt = StatementLogger.prepareStatement(connection, sql);
class StatementLogger {
static PreparedStatement prepareStatement(Connection connection, String sql) {
logger.info("Preparing SQL: " + sql);
return connection.prepareStatement(sql);
}
}
由于这一变化,看起来PreparedStatement的寿命比以前长得多。在两种情况下,该声明以完全相同的方式关闭。但随着变化,我们的数据库连接已经耗尽。
当然,在新版本中,对该语句的实时引用仍然存在时间稍长。这可能会让它有更好的机会幸存下来的小垃圾收集。但这种差异对我来说似乎微不足道。 (一帧弹出。)垃圾收集中是否有其他东西可以让它在第一种情况下将语句识别为短期对象,但在第二种情况下会将其识别为长寿命?
这可能会发生什么?
答案 0 :(得分:0)
对此更改的垃圾收集的唯一影响是创建了许多新的字符串,然后进行垃圾收集。
当您说您的数据库连接用尽时,这与GC处理的对象无关。您仍然可以泄漏Connection对象,但不会耗尽DB连接。你说你关闭连接?那你就不会用光了。
哦,由于负载模式的改变,现在可能正在观察问题,不一定是由于代码更改。