admin 管理员组

文章数量: 887021

OOM

一、背景

       项目程序是内嵌到APP的H5页面,从APP跳转进入H5页面需要调用APP系统的token认证接口,近期某个时间点出现登录验证失败情况,排查服务日志,发现token认证接口服务报错(java.lang.OutOfMemoryError: Java heap space)。

二、排查过程

       1、服务代码内存泄漏情况排查

            a、是否有循环引用情况

            b、长生命周期对象持有短生命周期对象的引用

                 (例子:全局静态map中缓存局部变量、且没有清空操作,map越来越大)

            c、长时间开启非常耗费资源的连接

       2、程序堆内存参数配置是否合理
             a、根据服务器资源情况配置,理论可配置服务器内存的1/4 (-Xmx1204M -Xms1024M)

             b、Xmx和Xms值尽量配置一致,不一样情况,初始化JVM堆内存空间较小,这会导致每当空间不够用的时候会向操作系统申请,需要进行一次GC

       3、收集oom日志,定位内存消耗情况

            a、java启动命令添加参数,当程序发生oom情况会输出详细日志

           (-Xmx1204M -Xms1024M -XX:+UseG1GC -XX:MaxGCPauseMillis=200 -XX:+DisableExplicitGC -XX:+HeapDumpOnOutOfMemoryError -XX:HeapDumpPath=/opt/logs/xxx-oom-error.log)

            b、参数含义:

             -Xms:初始堆大小

             -Xmx:最大堆大小

             -XX:+UseG1GC:使用G1垃圾回收器(JDK9默认是用G1为垃圾收集器,G1垃圾回收器将堆内存分割成不同的区域然后并发地对其进行垃圾回收)

             -XX:MaxGCPauseMillis:每次GC最大的停顿毫秒数(保证内存回收花费时间不超过停顿时间,默认无停顿时间,会影响吞吐量= 运行用户代码时间 / ( 运行用户代码时间 + 垃圾收集时间 )、视情况使用)

             -XX:+DisableExplicitGC:禁止显式执行GC,不允许通过代码来触发GC(System.gc() 无效果,视情况而使用)

             -XX:HeapDumpPath=/opt/logs/xxx-oom-error.log:错误日志输出位置

三、分析&定位

     1、打开jdk自带分析工具 - jvisualvm.exe(jdk bin目录里边)

          

     2、导入oom日志

     3、分析日志情况

 

          由类分析界面可知,有个实体类占用了94%多的内存且未被回收,导致oom情况。

四、总结

       1、排除代码功能是否有内存泄漏情况

       2、java 启动命令添加oom错误日志输出参数

       3、jvisualvm 工具分析oom错误日志定位问题

       由日志分析可知一个实体类对象内存占用过多,排查代码结合fastjosn低版本漏洞情况,将版本升级到1.2.83及以上,问题解决。

       此文仅记录解决问题的思路,如有错误之处,还望指出,感谢:)

本文标签: OOM