问题描述服务器在运行一段时间后(两三天),内存不断上升(可到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的错误,   
      晕,...........      
      希望高手能在此讨论一下,怎么解决?????      

解决方案 »

  1.   

    我觉的你应该先用Jprofiler看一下内存的使用情况,看看使用内存比较多的是那个对象,然后分析对象的属性和方法,看是不是有没有释放的内存。
      

  2.   

    你可以看看这个解决办法:
    http://www.neo.com.tw/archives/000482.html
    希望对你有帮助。
      

  3.   

    to:pl2e37mv(花令人韵) 
       我在tomcat设置了虚拟机的Initial memory pool (初始值) 和 Maximum memory pool (最大值) ,最大值设至了800M
      

  4.   

    >>我觉的你应该先用Jprofiler看一下内存的使用情况,看看使用内存比较多的是那个对象,然后分析对象的属性和方法,看是不是有没有释放的内存to ll42002(灰舌):
        在Jprofiler里看,heap区域还用很多可用内存,所以我一直怀疑是静态static方法和属性引起的java.lang.OutOfMemoryError: PermGen space的错误,查了一下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错误.,会不会太多的静态的对象/方法/属性会引起这个错误呢?