• OOM问题定位


        一:堆内存溢出

        Java创建的对象一般都是分配在堆中,如果是由于过期对象没能回收(内存泄漏)或者对象过多导致放不下(内存溢出),一般报错:

        Exception in thread "main" java.lang.OutOfMemoryError: Java heap space
            at java.util.Arrays.copyOf(Arrays.java:2760)
            at java.util.Arrays.copyOf(Arrays.java:2734)
            at java.util.ArrayList.ensureCapacity(ArrayList.java:167)
            at java.util.ArrayList.add(ArrayList.java:351)
            at test.java.VM.OOM.HeapOOM.main(HeapOOM.java:19)

         解决这部分的异常,重点是通过内存映像分析工具分析堆的转储快照,确定异常是由于内存泄漏还是内存溢出导致的。

         如果是内存泄漏导致的,则进一步查看泄漏对象到GCRoots的引用链,观察泄漏对象是通过怎样的路径与GCRoots相关联并导致垃圾回收器无法回收的;

         如果是内存溢出导致的,则检测堆的大小参数(Xmx、Xms)看看能否再调大,检测是否有某些对象生命周期过长。

        二:方法区溢出

        方法区主要存放类的信息、静态变量、常量池等,当常量池溢出或者不停地有类动态创建并加载时,方法区也能产生OOM。

        报错信息:

    Exception in thread "main" java.lang.OutOfMemoryError: PermGen space

          拓展:String.intern():如果字符串常量池已经包含一个等于此string对象的字符串,则返回该字符串;否则,将次string对象的内容加入到常量池中,并返回该对象的引用。

       三:栈溢出(虚拟机栈、本地方法栈)

       栈的异常有两种:

       JVM在执行方法时就会创建方法栈,方法的递归、调用等使得其他方法不停地入栈,其他方法执行完毕就会弹出栈帧。当一个方法栈的深度大于JVM所允许的深度时就会报StackOverFlow;一般,出现StackOverFlow时就要检查代码是否有无穷递归的情况出现了。

        stack length:1007Exception in thread "main" java.lang.StackOverflowError
    
            at test.java.VM.OOM.JavaVMStackOF.stackLeak(JavaVMStackOF.java:13)
            at test.java.VM.OOM.JavaVMStackOF.stackLeak(JavaVMStackOF.java:14)

       栈空间扩展时没有足够的内存则报OutOfMemory。

       四:本地直接内存溢出

       直接内存可以通过 -XX:MaxDirectMemorySize指定。如果本地直接内存溢出,我们可以发现堆转储快照中无明显异常指示,并且快照文件很小,而程序中又使用了NIO等技术,则可以检查是否直接内存溢出了。

  • 相关阅读:
    PyPi 是什么
    Python 项目结构
    Python 四舍五入函数 round
    Discourse 备份时间的设置
    Discourse 如何限制存储到 S3 的备份文件数量
    PHP中关于 basename、dirname、pathinfo 详解
    PHP中的魔术方法和关键字
    PHP中的排序函数sort、asort、rsort、krsort、ksort区别分析
    mysql cursor游标的使用,实例
    mysql 存储过程
  • 原文地址:https://www.cnblogs.com/ygj0930/p/6522987.html
Copyright © 2020-2023  润新知