zoukankan      html  css  js  c++  java
  • tomcat内存溢出的三种情况说明

      tomcat的内存溢出的本质其实就是JVM内存溢出,所以我们先了解以下javaJVM有关的内存知识。

      JVM管理两种类型的内存,堆和非堆,堆是给开发人员用的,是在JVM启动时创建;非堆是留给JVM自己用的,用来存放ClassMeta信息的。它和堆不同,GC不会在主程序运行期对这块内存空间进行清理。

      (1) 堆内存设置

        JVM堆的设置是指java程序运行过程中JVM可以调配使用的内存空间的设置。JVM的初始空间(即-Xms)默认是物理内存的1/64JVM最大空间(即-Xmx)默认是物理内存的1/4。默认空余堆内存小于40%时,JVM就会增大堆直到-Xmx的最大限制;空余堆内存大于70%时,JVM会减少堆直到-Xms的最小限制。

        因此一般情况下设置-Xms-Xmx相等以避免在每次GC 后调整堆的大小。可以利用JVM提供的-Xmn -Xms -Xmx等选项进行堆内存设置,一般的要将-Xms-Xmx选项设置为相同,而-Xmn1/4-Xmx值,堆的最大值设置不要超过可用物理内存的80%

      (2) 非堆内存PermGen space(全称Permanent Generation space)

        也称为永久保存的区域,用于存放ClassMeta信息,Class在被Load的时候被放入该区域。它和存放类实例(Instance)Heap区域不同,GC(Garbage Collection)不会在主程序运行期对PermGen space进行清理。JVM使用-XX:PermSize设置非堆内存初始值,默认是物理内存的1/64;由XX:MaxPermSize设置最大非堆内存的大小,默认是物理内存的1/4GC不会对PermGen space进行清理,所以如果加载很多的Class的话,就很有可能出现PermGen space的错误。


    以下我们针对tomcat内存溢出的三种情况做说明:


      1. OutOfMemoryErrorJava heap space 堆溢出

        这种情况属于JVM堆溢出,在JVM中如果98%的时间是用于GC且可用的Heap size 不足2%的时候就会抛出此异常。


      2. OutOfMemoryErrorPermGen space 非堆溢出

        这种错误常见于:

          (1) web服务器对JSP进行编译的时候;

          (2) 使用了大量的第三方jar, 其大小超过了jvm默认的大小(4M)

          (3) 项目应用有太多的class文件而恰好MaxPermSize设置较小;

          (4) tomcat热部署时侯不清理前面加载的环境,只将context更改为新部署的时候。


      3. OutOfMemoryErrorunable to create new native thread. 无法创建新的线程

        这种现象比较少见,也比较奇怪,主要是和jvm与系统内存的比例有关。

        具体的原因分析:每一个32位的进程最多可以使用2G的可用内存,因为另外2G被操作系统保留。这里假设使用1.5GJVM,那么还余下500M可用内存。这500M内存中的一部分必须用于系统dll的加载,那么真正剩下的也许只有400M,现在关键的地方出现了:当你使用Java创建一个线程,在JVM的内存里也会创建一个Thread对象,但是同时也会在操作系统里创建一个真正的物理线程(参考JVM规范),操作系统会在余下的400兆内存里创建这个物理线程,而不是在JVM1500M的内存堆里创建。在jdk1.4里头,默认的栈大小是256KB,但是在jdk1.5里头,默认的栈大小为1M每线程,因此,在余下400M的可用内存里边我们最多也只能创建400个可用线程。

        这样结论就出来了,要想创建更多的线程,就需要调整分配给JVM的最大内存。还有一种做法是让JVM宿主在你的JNI代码里边。


    下面总结一下javaJVM内存配置项:

    -Xmx Java Heap最大值,默认值为物理内存的1/4


    -Xms Java Heap初始值,ServerJVM最好将-Xms-Xmx设为相同值;


    -Xmn Java Heap Young区的值;


    -Xss 每个线程的Stack值;


    -XX:PermSize:设定内存的永久保存区域;


    -XX:MaxPermSize:设定最大内存的永久保存区域;


    -XX:NewSize:设置JVM堆的新生代的默认值;


    -XX:MaxNewSize:设置JVM堆的新生代的最大值;

     

     

    一些参考配置方案:

    1. 这种配置方案是我在eclipse集成tomcat做开发的时候使用的:

    -Xms1024m -Xmx1024m -Xmn256m -XX:PermSize=256M -XX:MaxPermSize=512m


    2. 这种配置方案是我在linux环境中配置tomcat的时候使用的:

    在bin文件夹下面创建文件setenv.sh,并保存以下内容:

    [root@localhost bin]# vim setenv.sh
    <!-- setenv.sh内容开始,其实就是声明环境变量 -->
    #!/bin/sh
    #Program:
    #   set tomcat environment variables.
    #History:
    #   2016/09/29 wy
                                                                                                                               
    JAVA_OPTS="-Xms1024m -Xmx1024m -Xmn256m"
    JAVA_OPTS="$JAVA_OPTS -server -XX:PermSize=128M -XX:MaxPermSize=512m"
    
    <!-- 保存以上内容到setenv.sh文件中 --> [root@localhost bin]
    # chmod -R 755 setenv.sh  <!-- 更改setenv.sh权限,设置为可执行 -->
  • 相关阅读:
    SQL中的数字格式化 (收藏)
    read about用法
    run into用法
    shoot for用法
    take off用法
    英语成语
    bring up用法
    satisfy with用法
    spend用法
    Linux环境进程间通信:共享内存
  • 原文地址:https://www.cnblogs.com/wy2185/p/5461008.html
Copyright © 2011-2022 走看看