【发布时间】:2021-11-04 22:48:15
【问题描述】:
我正在测试 PostgreSQL JDBC 驱动程序的附加属性,以检查它是否有助于找出连接泄漏。即使我特意不关闭Connection、PreparedStatement、ResultSet,也没有报错。
我怎样才能使logUnclosedConnections 工作。
这是我的示例程序
public static void main( String[] args ) throws Exception {
Properties dbProps = new Properties();
dbProps.setProperty( "user", "xxxxxxx" );
dbProps.setProperty( "password", "xxxxxxxxxx" );
dbProps.setProperty( "logServerErrorDetail", "true" );
dbProps.setProperty( "logUnclosedConnections", "true" );
dbProps.setProperty( "loggerLevel", "DEBUG" );
Connection conn = DriverManager.getConnection( "jdbc:postgresql://xxxxx.xxxxx.xxx:xxx/xxxxx", dbProps );
try {
PreparedStatement pstmt = conn.prepareStatement( "select count(*) from xx.xx limit 10" );
ResultSet rSet = pstmt.executeQuery();
while ( rSet.next() ) {
System.out.println( "count is " + rSet.getInt( 1 ) );
}
} catch ( Exception e ) {
e.printStackTrace();
}
}
结果是
count is 687
Sep 08, 2021 12:21:44 PM org.postgresql.Driver connect
FINE: Connecting with URL: jdbc:postgresql://xxxxx.xxxx.xxxx:xxx/xxxx
Sep 08, 2021 12:21:44 PM org.postgresql.jdbc.PgConnection <init>
FINE: PostgreSQL JDBC Driver 42.2.23
Sep 08, 2021 12:21:44 PM org.postgresql.jdbc.PgConnection setDefaultFetchSize
FINE: setDefaultFetchSize = 0
Sep 08, 2021 12:21:44 PM org.postgresql.jdbc.PgConnection setPrepareThreshold
FINE: setPrepareThreshold = 5
Sep 08, 2021 12:21:44 PM org.postgresql.core.v3.ConnectionFactoryImpl openConnectionImpl
FINE: Trying to establish a protocol version 3 connection to xxxx.xxxx.xxx:xxx
Sep 08, 2021 12:21:44 PM org.postgresql.core.v3.ConnectionFactoryImpl tryConnect
FINE: Receive Buffer Size is 65,536
Sep 08, 2021 12:21:44 PM org.postgresql.core.v3.ConnectionFactoryImpl tryConnect
FINE: Send Buffer Size is 65,536
Sep 08, 2021 12:21:44 PM org.postgresql.ssl.MakeSSL convert
FINE: converting regular socket connection to ssl
编辑 1
@Scary Wombat 和 @Stephen C 建议的更改,但结果相同。
未报告未关闭的连接。
public static void main( String[] args ) throws Exception {
Properties dbProps = new Properties();
dbProps.setProperty( "user", "postgres" );
dbProps.setProperty( "password", "AuR0ra$dba#$" );
dbProps.setProperty( "logServerErrorDetail", "true" );
dbProps.setProperty( "logUnclosedConnections", "true" );
dbProps.setProperty( "loggerLevel", "DEBUG" );
Connection conn = DriverManager.getConnection( "jdbc:postgresql://devdbmaster.koncert.com:5499/dev_koncert_v10.5", dbProps );
try {
for ( int i = 0; i < 100; i++ ) {
PreparedStatement pstmt = conn.prepareStatement( "select count(*) from cl.users limit 10" );
ResultSet rSet = pstmt.executeQuery();
while ( rSet.next() ) {
System.out.println( "count is " + rSet.getInt( 1 ) );
}
Thread.sleep( 10 );
}
} catch ( Exception e ) {
e.printStackTrace();
}
conn = null;
System.gc();
Thread.sleep( 1 );
}
编辑 2
按照 @Gus 和 @Stephen C
的建议,在System.gc(); 之前添加了 conn = null;
【问题讨论】:
-
最终这些对象将被垃圾回收,并且 finalize() 方法将被调用,如果调用者忽略了自己这样做,该方法将关闭连接。 我猜在这个没有发生 GC 的简单代码。
-
@ScaryWombat 关于如何完成这项工作的任何想法
-
循环大约几百次,可能还有一些睡眠时间。
-
我认为这里发生的情况是,在各个终结器需要运行之前,整个 VM 已被拆除。请注意,您在连接仍在范围内时调用了
System.gc(),并分配给了变量conn。因此,它无法被收集——就 JVM 而言,它仍在使用中,而且肯定不是不可访问的。可能在调用 gc 之前将conn设置为 null 就足够了。 -
@Gus 按照建议尝试,结果还是一样
标签: java postgresql jdbc