问题描述
|
我正在使用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的生存期似乎比以前更长。在两种情况下,该语句以完全相同的方式关闭。但是随着更改,我们用尽了数据库连接。
当然,对语句的实时引用在新版本中的生存时间略长。这可能会使其幸存较小的垃圾收集的几率更高。但是差异对我来说似乎微不足道。 (弹出一帧。)垃圾回收中是否还有其他东西可以让它在第一种情况下将语句标识为短期对象,而在第二种情况下将其标识为长期对象?
这可能是怎么回事?
解决方法
此更改对垃圾回收的唯一影响是创建了许多新的字符串,然后进行垃圾回收。
当您说数据库连接用完时,这与由GC处理的对象无关。您仍然可以泄漏Connection对象,但不能用完数据库连接。你说你关闭连接?这样您将不会用完。
哦,可能是由于负载模式更改(而不一定是由于代码更改)导致您正在观察此问题。