大话系统架构优化项目之服务端优化

这里写图片描述

【案例】记一次资源泄露,具体表现为ResultSet未关闭:
这里写图片描述
ResultSet未关闭统计

根据堆栈跟踪日志查看应用程序发现程序代码存在只关闭connection未关闭Statement和ResultSet的问题。

针对关闭connection是否会自动关闭Statement和ResultSet的问题,以及Statement和ResultSet所占用资源是否会自动释放问题,JDBC处理规范或JDK规范中做了如下描述:

JDBC处理规范

JDBC. 3.0 Specification——13.1.3 Closing Statement Objects

An application calls the method Statement.close toindicate that it has finished processing a statement. All Statement objectswill be closed when the connection that created them is closed. However, it isgood coding practice for applications to close statements as soon as they havefinished processing them. This allows any external resources that the statementis using to be released immediately.

Closing a Statement object will close and invalidateany instances of ResultSet produced by that Statement object. The resourcesheld by the ResultSet object may not be released until garbage collection runsagain, so it is a good practice to explicitly close ResultSet objects when theyare no longer needed.

These comments about closing Statement objects applyto PreparedStatement and CallableStatement objects as well.

JDBC. 4.0 Specification——13.1.4 Closing Statement Objects

An application calls the method Statement.close toindicate that it has finished processing a statement. All Statement objectswill be closed when the connection that created them is closed. However, it isgood coding practice for applications to close statements as soon as they havefinished processing them. This allows any external resources that the statementis using to be released immediately.

Closing a Statement object will close and invalidateany instances of ResultSet produced by that Statement object. The resourcesheld by the ResultSet object may not be released until garbage collection runsagain, so it is a good practice to explicitly close ResultSet objects when theyare no longer needed.

Once a Statement has been closed, any attempt toaccess any of its methods with the exception of the isClosed or close methodswill result in a SQLException being thrown.

These comments about closing Statement objects applyto PreparedStatement and CallableStatement objects as well.

规范说明:connection.close 自动关闭 Statement.close 自动导致 ResultSet 对象无效(注意只是 ResultSet 对象无效,ResultSet 所占用的资源可能还没有释放)。所以还是应该显式执行connection、Statement、ResultSet的close方法。特别是在使用connection pool的时候,connection.close 并不会导致物理连接的关闭,不执行ResultSet的close可能会导致更多的资源泄露。

JDK处理规范:

JDK1.4

Note: A ResultSet object is automatically closed by theStatement object that generated it when that Statement object is closed,re-executed, or is used to retrieve the next result from a sequence of multipleresults. A ResultSet object is also automatically closed when it is garbagecollected.

Note: A Statement object is automatically closed when it isgarbage collected. When a Statement object is closed, its current ResultSetobject, if one exists, is also closed.

Note: A Connection object is automatically closed when it is garbagecollected. Certain fatal errors also close a Connection object.

JDK1.5

Releases this ResultSet object’s database and JDBC resources immediatelyinstead of waiting for this to happen when it is automatically closed.

Note: A ResultSetobject is automatically closed by the Statement object that generated it whenthat Statement object is closed, re-executed, or is used to retrieve the nextresult from a sequence of multiple results. A ResultSet object is alsoautomatically closed when it is garbage collected.

规范说明:

1.垃圾回收机制可以自动关闭它们;

2.Statement关闭会导致ResultSet关闭;

3.Connection关闭不一定会导致Statement关闭。

现在应用系统都使用数据库连接池,Connection关闭并不是物理关闭,只是归还连接池,所以Statement和ResultSet有可能被持有,并且实际占用相关的数据库的游标资源,在这种情况下,只要长期运行就有可能报“游标超出数据库允许的最大值”的错误,导致程序无法正常访问数据库。

针对该类问题建议:

(1) 显式关闭数据库资源,尤其是使用Connection Pool的时候;

(2) 最优经验是按照ResultSet,Statement,Connection的顺序执行close;

(3) 为了避免由于java代码有问题导致内存泄露,需要在rs.close()和stmt.close()后面一定要加上rs = null和stmt = null,并做好异常处理;

(4) 如果一定要传递ResultSet,应该使用RowSet,RowSet可以不依赖于Connection和Statement。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值