与DB的网络连接未关闭

时间:2013-02-28 20:50:24

标签: java postgresql

我有一个守护进程,它大量使用后端PostgreSQL数据库。使用netstat我可以看到在ESTABLISHED中打开的数据库的网络连接稳定增加。

内存转储显示大量java.lang.ref.Finalizer。此外,线程转储显示:

中的所有线程
"pool-1-thread-6" prio=10 tid=0x0000000000e4d800 nid=0x10eb waiting on condition     [0x00007f3736c5b000]
 java.lang.Thread.State: WAITING (parking)
    at sun.misc.Unsafe.park(Native Method)
    - parking to wait for  <0x00000000c5524bf8> (a java.util.concurrent.locks.AbstractQueuedSynchronizer$ConditionObject)
    at java.util.concurrent.locks.LockSupport.park(LockSupport.java:186)
    at java.util.concurrent.locks.AbstractQueuedSynchronizer$ConditionObject.await(AbstractQueuedSynchronizer.java:2043)
    at java.util.concurrent.LinkedBlockingQueue.take(LinkedBlockingQueue.java:442)
    at java.util.concurrent.ThreadPoolExecutor.getTask(ThreadPoolExecutor.java:1068)
    at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1130)
    at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:615)
    at java.lang.Thread.run(Thread.java:722)

我怀疑这是因为我使用了一个固定的线程池Executor Service,这些线程显示Executor试图将有资源打开的线程结束。

这是我在各种数据库资源上调用close的地方:

    InitialContext ctx = null;
    Connection conn = null;
    PreparedStatement ps = null;
    ResultSet rs = null;

           ... 

    } finally {
        try {
            if (rs != null) {
                rs.close();
            }
        } catch (SQLException e) {
            Notification n = new Notification(this,e);
            n.log();
        }
        try {
            if (ps != null) {
                ps.close();
            }
        } catch (SQLException e) {
            Notification n = new Notification(this,e);
            n.log();
        }
        try {
            if (conn != null) {
                conn.close();
            }
        } catch (SQLException e) {
            Notification n = new Notification(this,e);
            n.log();
        }
        try {
            if (ctx != null) {
                ctx.close();
            }
        } catch (NamingException e) {
            Notification n = new Notification(this,e);
            n.log();
        }
    }

我花了相当多的时间在这上面,但无论我做什么,我似乎无法从这段代码中解脱出来。

如果可以,请提供帮助。

1 个答案:

答案 0 :(得分:1)

作为第一步,我建议使用新的自动资源管理功能来关闭您的连接等。

http://docs.oracle.com/javase/tutorial/essential/exceptions/tryResourceClose.html