C
creation-zy
Unregistered / Unconfirmed
GUEST, unregistred user!
我最近写了一个JSP应用,采用Apache Tomcat 4.0作为Web容器,出现了内存难以回收的问题。
我的代码架构如下:
DataProvider类负责管理数据库连接(采用单例模式确保多线程运行下也只有一个连接实例),
并且所有的SQL以及存储过程调用都被封装为函数,返回值一般为ResultSet;
数十个JavaBean,每个JavaBean都通过调用DataProvider对象的函数获取数据库信息(调用时
使用synchornized确保DataProvider对象在同一时刻只被一个线程使用);
一个SessionObj类作为中介者,处于JSP/Servlet和JavaBean之间。JavaBean都是在SessionObj
的函数内部生成,再以函数返回值的形式提供给使用者——JSP or Servlet;
每个登录成功的session都被绑定了一个SessionObj对象。SessionObj对象内部除了函数之外只
有几个int以及String变量,用于存放用户的关键信息(ID,Name等等)。
故障现象:
用户访问一般(不访问数据库或者数据量在几十个记录以下)的JSP页面时,Tomcat占用的
内存会有轻微的增加(刷新几次页面后回有4-300k的内存上升)——这不算什么。但是,一旦
用户访问的页面中有成百上千条记录时,每次内存使用都会上升1-2M!——更糟糕的是这些内
存迟迟不见被释放——我是在发现Tomcat报告“内存分配失败”错误时才发现这个问题的(那
时Tomcat占用了400多M内存——而应用刚启动不久才占用18到22M而已)。我在退出登录的界
面中已经调用了 session.invalid();
session=null;
——没有效果。
我的解决过程:
将System.gc()加入到一个JSP页面中,访问它——内存一般仅释放不到300K,有时甚至会
占用更多的内存?!
在一些频繁使用的JavaBean中增加static的引用计数变量,在JSP中观察它们的引用计数
——发现System.gc()调用可以很好的将它们释放——但是内存使用的下降非常有限。
做一个最简单的JSP,写上:
for(int i=0;i<100;i++) out.println("Hello world! "+i+"<br>");
然后不断的刷新该页面——很遗憾——内存的使用还是在不断上升——通过别的页面调用
System.gc()也没用...
最新的发现:
在我不断刷新页面、将Tomcat的内存占用提高到100多M之后,等待30min——session的持
续时间——发现内存恢复到最初的情况(20M左右)。如果在此之后再次进行操作,内存上升
的势头依然如故(不等到session超时内存就别想释放?!)。
将Web容器换成BEA公司的WebLogic 7,进行同样的操作,在Web应用的Monitor中可以看到
内存使用的短暂上升(上升幅度和Tomcat一样)——但是几秒之后就释放了。——难道这就
是Free和Not Free的本质区别吗?
请问各位同行有没有遇到类似的情况?是不是我的Tomcat配置有问题?(我没有改变过
Apache Tomcat 4.0的默认配置)
我的代码架构如下:
DataProvider类负责管理数据库连接(采用单例模式确保多线程运行下也只有一个连接实例),
并且所有的SQL以及存储过程调用都被封装为函数,返回值一般为ResultSet;
数十个JavaBean,每个JavaBean都通过调用DataProvider对象的函数获取数据库信息(调用时
使用synchornized确保DataProvider对象在同一时刻只被一个线程使用);
一个SessionObj类作为中介者,处于JSP/Servlet和JavaBean之间。JavaBean都是在SessionObj
的函数内部生成,再以函数返回值的形式提供给使用者——JSP or Servlet;
每个登录成功的session都被绑定了一个SessionObj对象。SessionObj对象内部除了函数之外只
有几个int以及String变量,用于存放用户的关键信息(ID,Name等等)。
故障现象:
用户访问一般(不访问数据库或者数据量在几十个记录以下)的JSP页面时,Tomcat占用的
内存会有轻微的增加(刷新几次页面后回有4-300k的内存上升)——这不算什么。但是,一旦
用户访问的页面中有成百上千条记录时,每次内存使用都会上升1-2M!——更糟糕的是这些内
存迟迟不见被释放——我是在发现Tomcat报告“内存分配失败”错误时才发现这个问题的(那
时Tomcat占用了400多M内存——而应用刚启动不久才占用18到22M而已)。我在退出登录的界
面中已经调用了 session.invalid();
session=null;
——没有效果。
我的解决过程:
将System.gc()加入到一个JSP页面中,访问它——内存一般仅释放不到300K,有时甚至会
占用更多的内存?!
在一些频繁使用的JavaBean中增加static的引用计数变量,在JSP中观察它们的引用计数
——发现System.gc()调用可以很好的将它们释放——但是内存使用的下降非常有限。
做一个最简单的JSP,写上:
for(int i=0;i<100;i++) out.println("Hello world! "+i+"<br>");
然后不断的刷新该页面——很遗憾——内存的使用还是在不断上升——通过别的页面调用
System.gc()也没用...
最新的发现:
在我不断刷新页面、将Tomcat的内存占用提高到100多M之后,等待30min——session的持
续时间——发现内存恢复到最初的情况(20M左右)。如果在此之后再次进行操作,内存上升
的势头依然如故(不等到session超时内存就别想释放?!)。
将Web容器换成BEA公司的WebLogic 7,进行同样的操作,在Web应用的Monitor中可以看到
内存使用的短暂上升(上升幅度和Tomcat一样)——但是几秒之后就释放了。——难道这就
是Free和Not Free的本质区别吗?
请问各位同行有没有遇到类似的情况?是不是我的Tomcat配置有问题?(我没有改变过
Apache Tomcat 4.0的默认配置)