zoukankan      html  css  js  c++  java
  • 项目总结65:内存溢出OOM问题处理

    项目总结65:内存溢出OOM问题处理

      OOM,即OutOfMemory,内存溢出,原因是:分配的太少;用的太多;用完没释放。理论上,JVM中除了程序计数器,堆内存,方法区,虚拟机方法栈,本地方法栈,都会出现OOM问题

    常见的OOM情况有三种:

      1- java.lang.OutOfMemoryError: Java heap space ------>java堆内存溢出,此种情况最常见,一般由于内存泄露或者堆的大小设置不当引起。对于内存泄露,需要通过内存监控软件查找程序中的泄露代码,而堆大小可以通过虚拟机参数-Xms,-Xmx等修改。

      2- java.lang.OutOfMemoryError: PermGen space/ Metaspace------>java永久代(元数据)溢出,即方法区溢出了,一般出现于大量Class或者jsp页面,或者采用cglib等反射机制的情况,因为上述情况会产生大量的Class信息存储于方法区。此种情况可以通过更改方法区的大小来解决,使用类似-XX:PermSize/MetaspaceSize=64m      -XX:MaxPermSize/MaxMetaspaceSize =256m的形式修改。另外,过多的常量也会导致方法区溢出。

      3- java.lang.StackOverflowError ------>不会抛OOM error,但也是比较常见的Java内存溢出。JAVA虚拟机栈溢出,一般是由于程序中存在死循环或者深度递归调用造成的,栈大小设置太小也会出现此种溢出。可以通过虚拟机参数-Xss来设置栈的大小。

    问题处理

    一、 OOM: Java heap space;

    问题示例:

        public static void main(String[] args) {
            //1- 堆内存溢出
            List<OOMObject> list = new ArrayList<>();
            int i = 0;
            while (true){
                list.add(new OOMObject());
                System.out.println(++i);
            }
        }
    日志:
    java.lang.OutOfMemoryError: Java heap space
    Dumping heap to D:/WORK/JVMjava_pid22096.hprof ...
    Exception in thread "main" java.lang.OutOfMemoryError: Java heap space
        at java.util.Arrays.copyOf(Arrays.java:3210)
        at java.util.Arrays.copyOf(Arrays.java:3181)
        at java.util.ArrayList.grow(ArrayList.java:261)
        at java.util.ArrayList.ensureExplicitCapacity(ArrayList.java:235)
        at java.util.ArrayList.ensureCapacityInternal(ArrayList.java:227)
        at java.util.ArrayList.add(ArrayList.java:458)
        at jvm.OOMTest.main(OOMTest.java:21)

    解决方案:

    1- 设置虚拟机运行参数,打印日志

    -server -Xms20m -Xmx20m -XX:+HeapDumpOnOutOfMemoryError -XX:HeapDumpPath=D:/WORK/JVM

    其中 -Xms20m -Xmx20m,是故意减少对内存,暴露问题;

    -XX:+HeapDumpOnOutOfMemoryError -XX:HeapDumpPath=D:/WORK/JVM;将OOM异常体脂打印到D:/WORK/JVM文件夹下,生成的文件如下:

     2- 使用jprofile软件打开hprof文件,如下图,分析问题原因;发现OOMObject对象被创建了81W次,导致内存溢出;

    3- 对症下药

    三、 StackOverflowError 异常

    示例

        public static void main(String[] args) {
            //2- 栈溢出
            recursion(0);
    
        }
    
        static int recursion(int num){
            if(num == 0){
                System.out.println(num);
                return recursion(num);
            }
            return 0;
        }
    }
    日志如下:
    Exception in thread "main" java.lang.StackOverflowError
        at sun.nio.cs.UTF_8$Encoder.encodeLoop(UTF_8.java:691)
        at java.nio.charset.CharsetEncoder.encode(CharsetEncoder.java:579)
        at sun.nio.cs.StreamEncoder.implWrite(StreamEncoder.java:271)
        at sun.nio.cs.StreamEncoder.write(StreamEncoder.java:125)
        at java.io.OutputStreamWriter.write(OutputStreamWriter.java:207)
        at java.io.BufferedWriter.flushBuffer(BufferedWriter.java:129)
        at java.io.PrintStream.write(PrintStream.java:526)
        at java.io.PrintStream.print(PrintStream.java:597)
        at java.io.PrintStream.println(PrintStream.java:736)
        at jvm.OOMTest.recursion(OOMTest.java:31)
        at jvm.OOMTest.recursion(OOMTest.java:32)

    解决方案:根据程序的.out日志文件(比如tomcat的catalina.out文件),排查问题出现在在哪里

    END

  • 相关阅读:
    How to interpret complex C/C++ declarations (ZT)
    The Managed Thread Pool
    How slow is dynamic_cast?
    Type Safety
    sBRDF空间双向反射分布函数完全解析
    近日工作与生活梗概
    简单的环绕散射 Simple Wrap Diffuse From GPU GEMS1
    屈辱史
    难以忽视的细节
    物理学与计算机图形学中的HDR
  • 原文地址:https://www.cnblogs.com/wobuchifanqie/p/13132560.html
Copyright © 2011-2022 走看看