介绍所过的项目中遇到的特别难解决的问题

我们的项目在测试阶段呢,首先是功能测试,然后是性能测试,最后是仿真测试;在功能测试和性能测试的过程中,项目运行良好,没有出现问题;但到了仿真测试阶段,在系统最初开始运行的一段时间呢,系统没有出现问题,7-8天后,系统开始出现运行缓慢的现象,在过一段时间之后,发现系统崩溃了。我们根据这个现象判断系统是出现内存泄露问题,所以使用了java内存检测工具jprofiler对系统内存进行检测,定位源码,发现内存中有大量的javabean占用资源,没有释放,随着系统运行时间的增长,这样没有释放的资源越来越多,最终导致内存泄露。

发现问题原因之后,我们开始着手修复,通过相应信息定位到代码块,发现我们在spring中定义了多个定时器,用来执行不同的操作,比如备份系统数据、数据转换、发送邮件等功能。通过百度搜索quartz,得知quartz有这样一个bug就是它会导致整个web应用的类加载器不能进行垃圾回收,在web应用关闭之后,会看到这个应用的所有静态类资源。也就是说,系统退出的时候没有释放相应资源。

Spring提供了一个名为org.springframework.web.util.IntrospectorCleanupListener的监听器,主要负责处理由于JavaBeans Introspector使用引起的内存泄露。这个监听器是在web应用关闭的时候。清除JavaBeans Introspector的监听器。Web.xml中注册这个listener,可以保证在web应用关闭的时候释放掉与这个web应用相关的class loader和由他管理的类。

所以,解决上述问题的办法就是,在web.xml中加入

org.springframework.web.util.IntrospectorCleanupListener

修复完成之后,我们重新进行了仿真测试,对测试跟踪一段时间之后,发现内存占用一直保持在一个比较稳定的状态,没有出现内存泄露问题,这个问题得到解决

我们知道servlet标准不允许在web容器内自行做线程管理,quartz的问题确实存在。对于web容器来说,最忌讳应用程序私自启动线程,自行进行线程调度,像quartz这种在web容器内部默认就自己启动了线程进行一步job调度的框架本身就是很危险的事情,很容易造成servlet线程资源回收不掉。

你可能感兴趣的:(介绍所过的项目中遇到的特别难解决的问题)