Chinaunix首页 | 论坛 | 博客
  • 博客访问: 1966998
  • 博文数量: 606
  • 博客积分: 9991
  • 博客等级: 中将
  • 技术积分: 5725
  • 用 户 组: 普通用户
  • 注册时间: 2008-07-17 19:07
文章分类

全部博文(606)

文章存档

2011年(10)

2010年(67)

2009年(155)

2008年(386)

分类: Java

2009-03-27 12:05:11

我用Java开发的web应用老是出现内存快速增长,最后内存溢出的问题。我用的tomcat5,JDK1.4.2,内存最大设为1498M,有时候也很平稳,但快速增长时,则只增不降,很快就内存溢出了。最近站点登录人数平均一天100人吧,即使几十人也有可能内存溢出。但登录人数多出现这种情况会更频繁。我查阅了很多技术资料,在一些内存开销大的模块都加了System.gc()语句,但都无法解决内存溢出。这次我采用的是四层架构,现将示例代码贴出来,请各位技术高手看看有没有问题。
1、WebUser类是映射web_user表字段的值对象类。
2、DbWebUserImpl实现了数据库表记录进行进行基本的增删改的类。
public class DbWebUserImpl implements DbWebUser{
Connection conn = null;

public Connection getConnection() {
return conn;
}

public void setConnection(Connection connection) {
this.conn=connection;
}

public void updateWebUser(WebUser webUser) throws Exception {
String strSql="update web_user set account=?,passwd=?,nickname=? where user_id=?";
PreparedStatement pstm=null;
try{
pstm=conn.prepareStatement(strSql);
int i=1;
pstm.setString(i++,webUser.getAccount());
pstm.setString(i++,webUser.getPasswd());
pstm.setString(i++,webUser.getNickname());
pstm.setInt(i++,webUser.getUser_id().intValue());
pstm.executeUpdate();
}finally{
if(pstm!=null){
pstm.close();
pstm=null;
}
}
}
}
3、WebUserService是服务层,调用数据访问类的方法,表示层(jsp或action)就直接调用WebUserService类的方法
public class WebUserService extends BaseService{
private DbWebUser dbWebUser=DbFactory.getDbWebUser();

public boolean updateWebUser(WebUser webUser){
Connection conn = null;
try{
conn=DataConnect.getConnection();
dbWebUser.setConnection(conn);
dbWebUser.updateWebUser(webUser);

return true;
}catch(Exception ex){
ex.printStackTrace();
message=ex.getMessage();
return false;
}finally{
try{
if(conn!=null) conn.close();
}catch(Exception ex){
ex.printStackTrace();
}
}
}
}
4、表示层(jsp或action)通过调用WebUserService类的updateWebUser方法,来更新web_user表的记录。
例如:
WebUserService webUserService=new WebUserService();
Authorization authorization=(Authorization)session.getAttribute("authorization");

WebUserForm f=(WebUserForm)form;
WebUser webUser=webUserService.getWebUser(authorization.getAccount());
webUser.setNickname(f.getNickname());
boolean bret=webUserService.updateWebUser(webUser);
//webUser=null;
请问各位高手,如果这里不加webUser=null,会不会造成内存泄漏?但我将很多类似的模块都加上了Object=null,仍不能解决内存溢出。

这个问题困惑了我很久,一直无法解决。现在论坛提出,请各位老师帮帮忙,非常感谢!

为了防止大家进行不必要的回复,现说明如下:
1、绝对没有任何地方连接没有关闭。我用三层架构做的另一套系统就好好的,有时候即使内存升至600M也会降下来,但现在我用四层架构做的这套系统,升上去就降不下来了。连接没有关闭这类问题一定做过认真的检查,否则不会到这儿来提问了。
2、我用Log4J将用户访问表示层和服务层的信息记录到日志文件中,发现内存猛增的时候用户的操作还是跟平时没什么区别,也看不出问题出在哪儿。如果是某些java代码执行造成死循环,应该用什么方法可以诊断出来。
3、曾在服务器上装过jprofile这个软件,但应用一启动,发现装上这个软件内存消耗太大。我在本地用jprofile这个软件也看不出来程序哪儿有问题。
最佳答案 最佳答案 此答案由提问者自己选择,并不代表爱问知识人的观点

[学弟]
最近在做一个网站,使用的编程语言是jsp,Web服务器采用Resin-2.1.6发布,操作系统使用Linux9.0,但是在网站运行过程中发现Java可用内存越来越少,有时程序会报出java.lang.OutOfMemoryError的错误,甚至导致Resin死机。
其实这种现象在Java语言中很正常,我们通常称之为Java内存溢出。由于我们在Java程序中声明了好多对象,占用了内存空间,程序结束时没有将这些对象或对象的引用进行释放,从而导致Java虚拟机(JVM)进行垃圾回收(GC)时,不能够回收这些对象。这样,Java所用的内存就会一直增加,直至溢出,进而导致Resin死机。
导致Java内存溢出的根本原因是Java程序的不规范或不健壮。因此,从根本上解决Java内存溢出的唯一方法就是修改Java程序,及时地释放没用的对象,释放内存空间。
除了这个方法以外,还有一些应急措施,可以临时缓解一下系统的运行。Resin默认情况是死机以后不能访问网站,必须手动重启Resin,但不可能一直看在机器旁边,看Resin有没有死机。所以这里介绍一种让Resin自重启的方法。
打开Resin的配置文件resin.conf(一般情况下,该文件在Resin目录的conf文件夹下)。里面有一段内容如下所示:

这段内容默认情况下是被注释的。它的功能是让Resin每隔一分钟就测试一下能否访问/ping/ping.jsp文件,测试时间是1s,假如不成功,就重试三次。假如三次都不成功,Resin就自动重启。所以将这段话下半部分(从"")的注释去掉,然后在Resin的发布目录中新建一个文件夹ping,在ping文件夹下新建一个ping.jsp文件,文件中可以写入简单的一句话,如:<% out.println("Hello world");%>。
好,大功告成,启动Resin,这样就不用担心Java内存溢出导致Resin死机了,因为Resin死机后会马上重新启动。
当然,这只是应急措施,不是长久之计。假如从长计议,还是要耐心的更改Java程序!!!
阅读(2105) | 评论(1) | 转发(0) |
给主人留下些什么吧!~~

chinaunix网友2009-04-28 21:11:33

∵ 最新公告 (2009年4月26日)   [UFO下载]:UFO 0.9999版发布(点此下载)。0.9999版进一步全面提高各种评测指标(如果您想知道Java的响应速度和运算速度可以做到多快,那么请您试用本0.9999版UFO!),提供详细的Howto文档(阅读此Howto文档)。UFO自0.975版以来已很稳定地运行(作为gm365网站的web server),不会出现一个字节的内存泄漏和一个线程的不能回收。 UFO:一个支持Jsp、Servlet、静态网页、虚拟主机、数据库连接池、http、https、无线互联网mimeType标准、认证和Tag库的Web Server。 使用UFO做Web Server的好处是网站能做得很稳定,永远也不会自己down掉;UFO在托管机房丢包率很高、遭受Hacker攻击、互联网 骨干网被黑等恶劣的环境条件下仍然能很好地运行;UFO在对付Hacker方面(防Hacker弄down和Hacker抓取不该访问的资源)也有足 够措施。 将网站做得很稳定是非常重要的: 1. 将网站做得很稳定,就可以天天睡大觉也收钱;相反网站