前几天遇到了OutofMemory的一个难题:我写的一个getTemplateAndData.java运行起来之后,会占用近100兆的内存,接着就OutOfMemory了。然后一行一行地看代码,看不出是哪个地方出错了。一行一行地调试,也不见出错,只见内存占用呼呼地向上长。
在网上查了不少贴子,基本都说是资源没有及时释放产生的问题。可是,我的代码倒底哪里还有资源没有释放呢?ResultSet只要语句结束就调用close,PreparedStatement也是及时地close。看了若干遍,调试了若干遍,当时真是接近气死了。偶尔发现一个贴子上说,PreparedStatement与ResultSet的close顺序是有讲究的,应该首先close掉PreparedStatement,然后再close掉ResultSet。眼前一亮,赶快动手,把三千多行的代码改了一遍,再运行,还是老样子,OutOfMemory。
2007-03-22 22:34:26 StandardWrapperValve[action]: Servlet.service() for servlet action threw exception
java.lang.OutOfMemoryError
还是得看代码。最后,试着多声明几个PreparedStatement,在ResultSet的循环中不再调用同一个PreparedStatment,竟然发现系统稳定下来了。如
stmt=cn.prepareStatement("select * from SomeTable");
rs=stmt.executeQuery();
while (rs.next()) {
stmtb=cn.prepareStatement("select * from SecondTable");
rsb=stmtb.executeQuery();
while (rsb.next()) {
}
}
原来问题竟然出在同一个PreparedStatement上,也就是说,如果当前的ResultSet没有close的话,调用PreparedStatement也没有作用。还是对Java的运行机制了解的比较浅,真是一个教训,费了两天的时间。如果有朋友看到这个文章的话,希望能有所启示,至少节省点时间吧。