正确使用JDBC数据库连接
April 29th, 2009
今天在写程序是时候遇到一个很诡异的内存问题,程序没有缓存任何东西,但是却使用了1G的内存。Java程序出现内存问题一样非常难以调试,由于是 程序自动回收,反而难以从程序本身入手。通常的原因是使用了对象却没有释放,也许我们认为应该释放了,但实际却没有被释放,或者在一些被封装的很深的地方 占用了大量的内存而没有被程序员所察觉。
Java里面有一些能够帮助找到内存泄漏的程序,其中Java Memory Profiler比较好用,免费的工具而且是图形化的界面。跑了一便程序后发现在jdbc哪里累计了很多的内存。回头来检查程序,发现唯一有可能的地方是 Connection,之前不是很确定应该每次使用时创建新的Connection还是是使用一个,Java的文档里面也并没有说使用 Connection应该注意什么。所以 便共享了一个Connection。改了程序后再跑,发现内存果然没有飞涨了。很明显Connection会使得数据库操作中的大量对象无法被释放,从而 导致内存泄漏,每次创建新的Connection,使用完后释放则没有问题。仔细想想Connection更多保存着和数据库操作相关的本地对象,对于数 据库来说维持一个Connection,在不做任何操作的情况下并不是太大的负担。
之后在网上找了一下,看到有一个人遇到和我类似的问题,页面在这里 。
把他的代码转过来
- Connection conn = null;
- ResultSet rs = null;
- PreparedStatement pss = null;
- try
- {
- conn = dataSource.getConnection(USERID,PASSWORD);
- pss = conn.prepareStatement(“SELECT SAVESERIALZEDDATA
- FROM SESSION.PINGSESSION3DATA WHERE SESSIONKEY = ?“);
- pss.setString(1,sessionKey);
- rs = pss.executeQuery();
- pss.close();
- conn.close();
- }
- catch (Throwable t)
- {
- // Insert Appropriate Error Handling Here
- }
- finally
- {
- // The finally clause is always executed - even in error
- // conditions PreparedStatements and Connections will always be closed
- try
- {
- if (pss != null)
- pss.close();
- }
- catch(Exception e) {}
- try
- {
- if (conn != null)
- conn.close();
- }
- catch (Exception e){}
- }
- }