`

Java web应用内存溢出 [已结帖,结帖人:pengble]

    博客分类:
  • Work
阅读更多

进入用户个人空间
加为好友
发送私信
在线聊天
  • pengble
  • 等级:
  • 可用分等级:乞丐
  • 总技术分:0
  • 总技术分排名:327011
  • 结帖率:100.00%
发表于:2008-02-22 21:30:07楼主
我用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,仍不能解决内存溢出。 

这个问题困惑了我很久,一直无法解决。现在论坛提出,请各位老师帮帮忙,非常感谢! 
 
 
问题点数:150 回复次数:22显示所有回复显示星级回复显示楼主回复 修改 删除 举报 引用 回复 
进入用户个人空间
加为好友
发送私信
在线聊天
  •  little06
  • 等级:
  • 可用分等级:掌柜
  • 总技术分:8855
  • 总技术分排名:2281
发表于:2008-02-22 22:05:521楼 得分:0
用jprofile查java使用内存的情况 
如果是Tomcat 
用probe来查看Tomcat的应用情况
 
修改 删除 举报 引用 回复 
进入用户个人空间
加为好友
发送私信
在线聊天
  •  little06
  • 等级:
  • 可用分等级:掌柜
  • 总技术分:8855
  • 总技术分排名:2281
发表于:2008-02-22 22:09:022楼 得分:0
数据库最重要是不要存在死锁 
可以的话,把不是必须的地方换成缓存吧 

还有 内存溢出不一定多是数据库连接的问题 
也可能是其他java代码执行成死循环 或者出错 
造成资源没有释放 
 
修改 删除 举报 引用 回复 
进入用户个人空间
加为好友
发送私信
在线聊天
  •  kokobox
  • 等级:
  • 可用分等级:富农
  • 总技术分:23345
  • 总技术分排名:500
发表于:2008-02-22 23:30:093楼 得分:0
查查有没有连接没有关闭的,有没有定时器之类的 

有没有输入输出流忘记关闭的。仔细查查。 

 
修改 删除 举报 引用 回复 
进入用户个人空间
加为好友
发送私信
在线聊天
  •  pengble
  • 等级:
  • 可用分等级:乞丐
  • 总技术分:0
  • 总技术分排名:327011
发表于:2008-02-23 09:36:094楼 得分:0
谢谢上面几位的回复,现说明如下: 
1、绝对没有任何地方连接没有关闭。我用三层架构做的另一套系统就好好的,有时候即使内存升至600M也会降下来,但现在我用四层架构做的这套系统,升上去就降不下来了。连接没有关闭这类问题一定做过认真的检查,否则不会到这儿来提问了。 
2、我用Log4J将用户访问表示层和服务层的信息记录到日志文件中,发现内存猛增的时候用户的操作还是跟平时没什么区别,也看不出问题出在哪儿。如果是某些java代码执行造成死循环,应该用什么方法可以诊断出来。 
3、曾在服务器上装过jprofile这个软件,但应用一启动,发现装上这个软件内存消耗太大。我在本地用jprofile这个软件也看不出来程序哪儿有问题。
 
修改 删除 举报 引用 回复 
进入用户个人空间
加为好友
发送私信
在线聊天
  •  pengble
  • 等级:
  • 可用分等级:乞丐
  • 总技术分:0
  • 总技术分排名:327011
发表于:2008-02-23 17:39:335楼 得分:0
请各位技术高手帮帮忙,非常感谢!
 
修改 删除 举报 引用 回复 
进入用户个人空间
加为好友
发送私信
在线聊天
  •  yill
  • 等级:
  • 可用分等级:长工
  • 总技术分:5
  • 总技术分排名:256989
发表于:2008-02-24 02:02:426楼 得分:0
一般内存泄露的原因都会在线程操作、数据库或者文件等操作上面 。 

要定位的话可以借助工具,比如你说的 jprofile 或者 optimize,不过工具对原有系统的影响是很大的。 

这种情况下,可以打开java 的 gc 参数,关注堆内存是否有持续增加。 

程序运行过程中可以打 java 进程的堆栈信息分析线程 情况,看是否有线程等待、死锁等情况。 

另外,内存溢出一般会有异常堆栈或者core文件吧,这个也要好好分析一下。
 
修改 删除 举报 引用 回复 
进入用户个人空间
加为好友
发送私信
在线聊天