美文网首页
JAVA的三种溢出

JAVA的三种溢出

作者: 你比大笨钟还笨 | 来源:发表于2018-10-25 16:32 被阅读0次

    一、堆内存溢出 Java heap space(老年代,java存放对象实例的地方)

    发生原因:java虚拟机创建的对象太多,在垃圾回收时,分配的堆内存空间被占满,即老年代满了无法再进行回收分配。
    发现问题:压测时看到抛出的java.lang.OutOfMemoryError: Java heap space。
    定位问题:可在tomcat/logs 下使用命令,jmap -histo pid 查看堆内存快照信息,信息里看是否有自己公司的调用方法.
    如果有,则可以确定该方法有问题,查看该方法(例如:查看该方法发现调用后没有被释放)。
    解决问题:手动释放掉。
    如果没找到公司内部的调用方法呢?
    1.用线下工具mat分析;
    2.用jmap -heap +pid 查看内存使用情况。

    二、非堆内存溢出 Java lang(tomcat,持久代)

    发生原因:程序中使用了大量的jar或者class,使虚拟机装载类的空间不够。
    发现问题:压测时看到抛出的java.lang.OutOfMemoryError: PermGen space
    定位问题:持久代空间不够。
    解决问题:增大tomcat中默认的持久代空间大小,/tomcat/bin/catalina.sh 文件中增加/修改
    JAVA_OPTS="-XX:PermSize=64m -XX:MaxPermSize=150m"
    其中XX:PermSize是初始持久代大小,XX:MaxPermSize是最大持久代大小

    三、线程栈溢出

    发生原因:请求新建栈帧时,栈所剩空间小于栈帧所需空间。
    例如:递归调用、大量的循环/死循环、全局变量过多、数组/List/map数据过大,都有可能造成线程栈溢出。
    发现问题:1.java.lang.StackOverflowError(方法调用层次太深,内存不够新建栈帧)
    2.java.lang.OutOfMemoryError:unable to create new native thread(线程太多,内存不够新建线程)
    定位问题:
    如果是问题1,则看是否调用了递归、使用了大量循环等;
    例如:通过递归调用方法,不停的产生栈帧,一直把栈空间堆满,直到抛出异常
    如果是问题2,则查看线程占用的栈空间(Xss)和线程栈的总空间。例如:
    ①虚拟机参数Xss调大了,每个线程占用的栈空间也就变大了,那么可以建立的线程数量必然减少;
    ②java总内存(Xmx)和持久代空间(-XX:MaxPermSize)过大,留给线程栈的可用空间就少,在线程栈空间不变的情况下,可创建的线程数越来越小。
    解决问题:
    1.优化代码;
    2.调小线程占用的栈空间、增大线程栈的总空间。

    参考文档
    http://blog.sina.com.cn/s/blog_701c951f0100n1sp.html

    相关文章

      网友评论

          本文标题:JAVA的三种溢出

          本文链接:https://www.haomeiwen.com/subject/xpdctqtx.html