JDBC中关于Connection, PreparedStatement, ResultSet是否关闭的一些思考
2016-04-07 10:25
525 查看
如果你不使用连接池,那么就没有什么问题,一旦Connection关闭,数据库物理连接就被释放,所有相关Java资源也可以被GC回收了。但是如果你使用连接池,那么请注意,Connection关闭并不是物理关闭,只是归还连接池,所以PreparedStatement和ResultSet都被持有,并且实际占用相关的数据库的游标资源,在这种情况下,只要长期运行,往往就会报“游标超出数据库允许的最大值”的错误,导致程序无法正常访问数据库。
在使用java开发后台应用程序的时候,如果需要使用数据库,特别是试用第三方的数据库连接池的时候,使用完PreparedStatement等一定要手动关闭,最好是将关闭的代码写到finally中,保证一定能够完成关闭。
原因有如下两点:
1、第三方的数据库连接池,使用的时候,获取到Connection之后,使用完成,调用的关闭方法(close()) ,并没有将Connection关闭,只是放回到连接池中,如果调用的这个方法,而没有手动关闭PreparedStatement等,则这个PreparedStatement并没有关闭,这样会使得开发的程序内存急速增长,java的内存回收机制可能跟不上速度,最终造成Out of memory Error。
2、如过在PreparedStatement等调用的时候,发生异常,则这个PreparedStatement是没有被关闭的,因此最好将PreparedStatement等的关闭写到finally代码中。下面是本人
在本机上试过的一个测试实例
可以自行用类似于上述的代码测试一下 , 测试的时候关注本机物理内存的占用状况
在有resultSet.close()这句代码的时候,内存占用并不会发生太大变化,而一旦不关闭结果集,内存占用将会急速增长,甚至程序被hang住,我猜测可能就是上述所说的“游标超出数据库允许的最大值”,就算不阻塞,内存占用继续增长,将出现内存溢出问题
在使用java开发后台应用程序的时候,如果需要使用数据库,特别是试用第三方的数据库连接池的时候,使用完PreparedStatement等一定要手动关闭,最好是将关闭的代码写到finally中,保证一定能够完成关闭。
原因有如下两点:
1、第三方的数据库连接池,使用的时候,获取到Connection之后,使用完成,调用的关闭方法(close()) ,并没有将Connection关闭,只是放回到连接池中,如果调用的这个方法,而没有手动关闭PreparedStatement等,则这个PreparedStatement并没有关闭,这样会使得开发的程序内存急速增长,java的内存回收机制可能跟不上速度,最终造成Out of memory Error。
2、如过在PreparedStatement等调用的时候,发生异常,则这个PreparedStatement是没有被关闭的,因此最好将PreparedStatement等的关闭写到finally代码中。下面是本人
在本机上试过的一个测试实例
public static List<OrgzMetaDto> queryMetaByOrgzName1() { String sql = "SELECT * FROM test_table limit 0, 10000"; List<OrgzMetaDto> orgzs = new ArrayList<OrgzMetaDto>(); try { pst = conn.prepareStatement(sql); ResultSet resultSet = pst.executeQuery(); while (resultSet.next()) { OrgzMetaDto dto = new OrgzMetaDto(); dto.setUuid(resultSet.getString("uuid")); orgzs.add(dto); } resultSet.close(); } catch (Exception e) { e.printStackTrace(); } return orgzs; } public static void main(String[] args) throws Exception { for (int i=0; i<1000; i++) { System.out.println(i); queryMetaByOrgzName1(); } }
可以自行用类似于上述的代码测试一下 , 测试的时候关注本机物理内存的占用状况
在有resultSet.close()这句代码的时候,内存占用并不会发生太大变化,而一旦不关闭结果集,内存占用将会急速增长,甚至程序被hang住,我猜测可能就是上述所说的“游标超出数据库允许的最大值”,就算不阻塞,内存占用继续增长,将出现内存溢出问题
相关文章推荐
- C++第三次实验1-个人所得税计算器
- AngularJS 模态对话框
- MAT使用
- SoundPool的使用
- dpi 、 dip 、分辨率、屏幕尺寸、px、density 关系以及换算
- Linux 上格式化ssd硬盘操作步骤
- MySQL如何发型不乱的应对半年数十TB数据增量
- Eclipse建springmvc项目资料整理
- Spark初试之WordCount
- android开发判断手机网络连接状态
- 4.1.2.1 MASTER_SERV结构体
- 虚幻4 小笔记
- 仿京东导航
- Android 性能典范:拯救计划
- 在BackGroundWorker中使用ArcGIS组件
- MyBatis 配置sql语句输出
- Shiro学习(7)与Web整合
- Spring如何加载XSD文件(org.xml.sax.SAXParseException: Failed to read schema document错误的解决方法)
- SSH中的error解决
- C与C++中的常用提高程序效率的方法