Java内存不足之PermGen space(Tomcat报错)

来源:互联网 发布:小众运动鞋知乎 编辑:程序博客网 时间:2024/06/04 18:00

1.普通程序与java程序的运行对比

普通程序在运行时

  • 程序 —–编译成—–>二进制码/机器码(机器码与硬件底层相关)–>机器码绑定底层 So:不同平台下的程序只能在相应的操作系统、硬件(体系结构)上,就比如pc机的程序不能在mac上运行。

Java程序在运行时:

  • java程序 —–编译成—–>java class(字节码,与平台无关,在任何的操作平台上字节码都是相同的 –>JVM(java虚拟机,负责将字节码编译成相应体系结构的代码)–>在相应的平台中运行。

2. OutOfMemoryError: PermGen space

  • 当永久保存区域的空间耗尽时OutOfMemoryError: PermGen
    space就会发生,这个错误一般是由于内存泄漏导致的。所谓内存泄漏,是指java类和类加载器在被取消部署后不能被垃圾回收。怎么会发生这种情况呢?举个例子:假如我们有一个Student类,这个类是Web应用程序jar包的一部分,同时在Web服务器的lib文件夹中包含了某种日志框架,其中有一个Log类提供register方法调用,从而使得别的类通过注册就可以使用日志功能。如果Student类被注册了,那么Log类就开始拥有了一个对Student对象的引用(reference)。当Student类取消部署时,它仍然是注册Log类的,Log类仍然拥有对Student对象的引用,因此,Student对象永远不会被垃圾回收。此外,由于Student对象拥有一个对它的ClassLoader的引用,所以ClassLoader本身永远也不会被垃圾回收,从而导致由它加载的所有类都不会被回收。

  • 一个更为典型的例子是使用代理对象。Spring和Hibernate常常为某些类生成代理类,这些代理类也是通过类加载器加载的,并且存储在永久保存区域的堆空间,它们永远不会被丢弃,从而会导致永久保存区域的堆空间被填满。

3.如何避免永久保存区域内存不足

  1. 增加PermGen堆的最大尺寸    当遇到java.lang.OutOfMemoryError:PermGen
    space错误时,我们可以做的第一件事情是增加永久保存区域的最大尺寸,该尺寸的缺省设置是64 M,我们可以将它设置成128
    M以上。这个工作不能通过常规的JVM参数
    -Xms(设置初始堆大小)和-Xmx(设置最大堆大小)来完成,因为前面已经提到,永久保存区域完全独立于普通的Java堆,这些参数是用来设置普通的Java堆的。不过也有类似参数用于设置永久保存区域的规模:

    java -XX:MaxPermSize=128 M

      该设置将永久保存区域设置为128 M,这个大小是默认设置的两倍。

    SET JAVA_OPTS=-XX:PermSize=64 M -XX:MaxPermSize=128 M

  2. 避免使用静态字段   确保在编写Java类时,不要使用静态变量作为对其他对象的引用。

  3. 使用JDK动态代理,而不是CGLIB代理   一些第三方的框架,如CGLIB会吞食大量的PermGen。因此,当遇到PermGen错误时,应尽快升级cglib到最新版;改用JDK动态代理,也是一个不错的选择。

  4. 更新到最新版本Hibernate3.2   此外,新版本的Hibernate不再使用CGLIB作为字节码提供者了,所以及时升级Hibernate,会大大降低出错的机会。

  5. 共用的jar文件放到共享目录下   如果在服务器上同时发布了多个应用,那么应该把共用的jar文件放到所有应用都可以访问的目录下。针对Tomcat而言,如果Tomcat下面有多个应用,应尽可能地把lib目录下共用的jar文件放到Tomcat的common\lib或shared\lib下,以避免重复发布,发布速度和运行速度上也会有所提升。


  • 转载:http://www.cnblogs.com/iliuyuet/p/4315969.html
阅读全文
0 0
原创粉丝点击