问题描述 服务器在运行一段时间后(两三天),内存不断上升(可到900M),经常出现java.lang.OutOfMemoryError: PermGen space的错误,导致tomcat死机,外部不能找开网站. 目前,web服务和数据库服务是分开的,web服务器是2005年9月才升级的, 内存2G,内存泄漏基本可以确定为Web服务器软件环境引起的. Web服务器的软件环境如下: 操作系统:Win2000 server Web服务:tomcat5.5 Jdk版本:jdk1.5 网站开发先后经历了三次大的调整,开发环境从最初的jdk1.4,tomcat4.0 升级到了现在的jdk1.5,tomcat5.5, 技术上也由当初的javabean+jsp,增加了struts,sql mapping,jstl,displaytag,另外,后台还同时运行了多个进程,以实现邮件的订阅,测评刷新,职位刷新,RSS刷新等功能 解决方案 鉴于以上情况,我通过以下步骤来排除内存泄漏的问题: 1. 根据近段时间的日志文件,发现有些情况下,死机前后,都是有后台线程启动,如”职位刷新””RSS刷新”,所以我准备先停止后台线程的自动运行,改成手动启动,以测试是否因为后台线程自动运行引起的干扰. 2. 错误java.lang.OutOfMemoryError: PermGen space,倒底是不是因为对象内存占用过多,没有被虚拟机JVM回收的原因引起,这点我一直有疑问. 查了一下PermGen space,全称是Permanent Generation space,就是说是永久保存的区域,用于存放 Class和Meta信息,Class在被Load的时候被放入该区域,从字面看,和存放Instance的Heap区域不同,GC(Garbage Collection)应该不会对PermGen space进行清理,所以如果你的APP会LOAD很多CLASS的话,就很可能出现PermGen space错误. 所以我怀疑是我们源代码是使用了太多的静态static对象/方法/属性 所引起的,因为静态的对象/方法/属性是和类关联的,不被虚拟机JVM回收.正像上面说的, 如果你的APP会LOAD很多CLASS的话,就很可能出现PermGen space错误.,会不会太多的静态的对象/方法/属性会引起这个错误呢? 这点是我自己的理解,如果要验证,需要改写所有的静态的对象/方法/属性,这个工作量是巨大的(如果万一不是?),所以为了减小风险,我准备改写最常用的类(如查职位,文章显示)为非静态方法,如果能有一些效果(如死机的频率减少),再作进一步修改. 3. 更换tomcat版本,排除tomcat旧版本bug引起的内存泄漏问题. 以下是一个blog上发现的,和我们的问题比较类似. Tomcat 5.5.4有内存泄漏的问题,当我重新发布一个应用几次之后,Outofmemory:PermGen space,到apache的网站上找,说是5.5.8会修补这个问题。所以还是不要重新发布了,直接重起得了:) 4. 使用工具Jprofiler,实时监控服务器运行情况,当发现死机时,查看其内存使用情况,类和对象占用的内存大小等… Jprofiler可以监控内存堆栈的分配和使用情况、对象建立的多少情况、cpu使用的情况,还可以针对每个类或每个对象或每个线程、或每个函数对内存、cpu的使用情况,还可以看java虚拟机中自动垃圾收集的运行情况 5. 使用测试工具loadrunner,加大负载,模拟并发的大访问量. 周末两天,服务器没有死,但内存已到了860M之多.... 周一上午来上班的时候,就死了,还是java.lang.OutOfMemoryError: PermGen space的错误, 晕,...........