精华内容
下载资源
问答
  • OOM问题排查思路与常用指令
    千次阅读
    2021-01-17 15:18:15

    OOM问题排查思路与指令

     

    实际生产项目中,不可避免的会遇到服务器内存不足引发告警的问题,很多时候可能就是因为部署的服务占用了太多的内存导致的。

    当然,我们可以通过设置java的内存参数来控制内存的最大占用量,但是JVM内存不足了也是一个很头疼的问题。

    如果服务部署的时候,允许外部内存检查等VM之类的工具远程连接还好,但是很多公司出于性能等种种原因,并不会开放远程连接的功能。

    这样的话,就只能通过指令来定位问题了!

     

    常用指令:

    1.top指令:

    类似windows环境的任务管理器,可以看到各个进程的使用情况。然后ctrl+m进行排序,找出内存消耗最高的几个进程。

    根据pid,查询性能消耗比较高的是什么服务在运行l

    ps -ef|grep 26810

    2.jstat :虚拟机统计信息监视工具

    jstat是用于监视虚拟机各种运行状态信息的命令行工具。可以显示进程中的类加载、内存、垃圾收集、即时编译等运行数据

    常用到的如下:

    1.jstat  -gc  ***   间隔时间     输出条数   (监视java堆状况,包括Eden区、2个Survivor区,老年代、永久代等的容量,已用空间,垃圾收集时间合计等信息)

    2.jstat  -gcutil  ***   (监视内容与-gc类似,但输出主要关注已使用空间占用总空间的百分比)

    3.jmap : java内存映射工具

    jmap (Memory Map for Java) 命令用于生成堆转储快照(一般称为:heapdump或dump文件)

    更多相关内容
  • 上周运维反馈线上程序出现了OOM,程序日志中的输出为 Exception in thread http-nio-8080-exec-1027 java.lang.OutOfMemoryError: Java heap space Exception in thread ...
  • 线上OOM问题排查

    2021-11-10 13:06:25
    这段时间公司在搞活动,系统的订单量比平时增加了好几倍,活动开始的第一天下午,业务反馈说系统崩溃了,然后开始排查原因,发现服务并没有挂,只是响应速度异常慢。查看了cpu和内存,发现cpu是正常的,内存也是够用...

    这段时间公司在搞活动,系统的订单量比平时增加了好几倍,活动开始的第一天下午,业务反馈说系统崩溃了,然后开始排查原因,发现服务并没有挂,只是响应速度异常慢。查看了cpu和内存,发现cpu是正常的,内存也是够用的,说明机器的cpu和内存都没有问题。

    top #查看cpu和内存的使用情况

     

    然后查看这个服务的堆使用情况,发现老年代已经满了,在频繁fullGC,并且每次fullGC回收的内存都很少。于是找运维重启了服务,重启后服务恢复正常了,先解决问题再找原因。通过监控堆栈的使用情况,发现老年代增长速度很快,如下图,但是每次老年代回收极少,考虑可能存在内存泄漏,服务启动一次只能勉强撑1个小时,然后找运维把堆扩大到(3G),然后设置定时重启,每三个小时自动重启服务,让服务基本保持正常,然后继续抓紧排查问题。

    jps  #查看Java进程及pid
    jstat -gcutil pid 1000   #1000表示时间间隔

     

    S0C:第一个幸存区的大小
    S1C:第二个幸存区的大小
    S0U:第一个幸存区的使用大小
    S1U:第二个幸存区的使用大小
    EC:伊甸园区的大小
    EU:伊甸园区的使用大小
    OC:老年代大小
    OU:老年代使用大小
    MC:方法区大小
    MU:方法区使用大小
    CCSC:压缩类空间大小
    CCSU:压缩类空间使用大小
    YGC:年轻代垃圾回收次数
    YGCT:年轻代垃圾回收消耗时间
    FGC:老年代垃圾回收次数
    FGCT:老年代垃圾回收消耗时间
    GCT:垃圾回收消耗总时间

    开始想办法排查内存泄漏问题,使用jmap查看占用内存最大的对象,结果不太理想,只看到char,string还有hashmap占用了大量内存。最开始走了些弯路,怀疑代码中是不是hashmap有内存泄漏了,结果找了半天没有找到可疑的地方。

    jmap -histo 1 | head -20 #查看占用内存最大的前20个对象

     

    那只能把堆dump出来在本地分析,毕竟线上服务不能停,考虑怎么安全地把堆dump出来,想到了用jmap或者是arthas。jmap -dump有个问题,这个命令执行,JVM会将整个heap的信息dump写入到一个文件,heap如果比较大的话,就会导致这个过程比较耗时,并且执行的过程中为了保证dump的信息是可靠的,所以会暂停应用。所以jmap被pass了,于是找运维安装了arthas。

    arthas下载地址:curl -O https://arthas.aliyun.com/arthas-boot.jar

    #启动arthas
    java -jar arthas-boot.jar
    #提示选择进程,输入编号选择对应的进程

     

    dashboard #查看仪表板

    headdump #dump堆栈信息,速度很快,900多M的堆几秒钟就dump完了

     

    然后把dump文件下载到本地,开始分析dump文件,分析dump文件常用的工具有jdk自带的jvisualvm,eclipse的MAT,我开始是用jvisualvm分析,效果不理想,可以看到Integer,HashMap占用内存很大,但是也说明不了问题,如下图,后来改用MAT分析,发现这个功能很好用,推荐用MAT分析堆栈

     

    使用MAT分析如下,发现org.hibernate.internal.SessionFactoryImpl占用了大量内存,进一步展开这个类,发现是queryCacheplan占用了很多内存,最终在queryCacheplan中找到了罪魁祸首,代码里面写了in查询,结果这个in查询的条件有800多,类似这样的sql还有很多,难怪内存会不断增长,sql语句如下:

    select distinct xxxEntity1
    from xxxEntity1 xxxEntity1
      inner join xxxEntity2 xxxEntity2 with xxxEntity1.deliveryNo = xxxEntity2.order_No
    where xxxEntity.type = ?1 and xxxEntity1.caseNo in (?2, ?3, ?4, ?5, ........ ?864, ?865, ?866)

     

    然后找到代码中这个sql语句,优化后重新上线,问题解决了,已经跑了很多天一直很正常。

    QueryPlanCache 内存泄漏解决方法

    产生的原因: hibernate中的QueryPlanCache会缓存sql,以便于后边的相同的sql重复编译。如果in后的参数不同,hibernate会把其当成不同的sql进行缓存,从而缓存大量的sql导致heap内存溢出。

    解决方法: 通过设置缓存最大值来进行限制,不设置默认是2G。

    spring:
      jpa:
        properties:
          hibernate:
            query:
              plan_cache_max_size: 64
              plan_parameter_metadata_max_size: 32
              plan_cache_max_soft_references: 1024
              plan_cache_max_strong_references: 64

    展开全文
  • 一次线上OOM问题排查

    千次阅读 2019-08-05 21:29:22
    二、问题排查 1、出现OOM问题了,脑袋里第一反应就是项目中出现内存泄露或者内存溢出了。先登录ELK,根据关键词 “java.lang.OutOfMemoryError” 进行搜索,果然发现有OOM错误日志。 org.springframework.scheduling...

    一、短信预警
    某天下午风和日丽,下午五点钟早早的就发版上线。七点准备下班的时候突然收到短信预警,项目OOM了,wtf !!!

    二、问题排查
    1、出现OOM问题了,脑袋里第一反应就是项目中出现内存泄露或者内存溢出了。先登录ELK,根据关键词 “java.lang.OutOfMemoryError” 进行搜索,果然发现有OOM错误日志。

    org.springframework.scheduling.quartz.JobMethodInvocationFailedException: Invocation of method 'run' on target class [class com.kingdee.finance.data.credit.ydreport.task.YdReportAppendixInfoTask] failed; nested exception is java.lang.OutOfMemoryError: Java heap space
        at org.springframework.scheduling.quartz.MethodInvokingJobDetailFactoryBean$MethodInvokingJob.executeInternal(MethodInvokingJobDetailFactoryBean.java:266)
        at org.springframework.scheduling.quartz.QuartzJobBean.execute(QuartzJobBean.java:75)
        at org.quartz.core.JobRunShell.run(JobRunShell.java:213)
        at org.quartz.simpl.SimpleThreadPool$WorkerThread.run(SimpleThreadPool.java:557)
    Caused by: java.lang.OutOfMemoryError: Java heap space
        at java.util.Arrays.copyOf(Arrays.java:3332)
        at java.lang.AbstractStringBuilder.expandCapacity(AbstractStringBuilder.java:137)
        at java.lang.AbstractStringBuilder.ensureCapacityInternal(AbstractStringBuilder.java:121)
        at java.lang.AbstractStringBuilder.append(AbstractStringBuilder.java:622)
        at java.lang.StringBuffer.append(StringBuffer.java:383)
        at java.net.URLEncoder.encode(URLEncoder.java:271)
        at com.longsec.http.HttpConnection.httpPostWithJSON(HttpConnection.java:548)
        at com.kingdee.finance.data.credit.ydreport.service.impl.YdCreditAppendixInfoHandler.sendRequest(YdCreditAppendixInfoHandler.java:151)
        at com.kingdee.finance.data.credit.ydreport.service.impl.YdCreditAppendixInfoHandler.handleAppendixRequest(YdCreditAppendixInfoHandler.java:46)
        at com.kingdee.finance.data.credit.ydreport.service.impl.YdCreditAppendixInfoHandler$$FastClassBySpringCGLIB$$a4a2cc16.invoke(<generated>)
        at org.springframework.cglib.proxy.MethodProxy.invoke(MethodProxy.java:204)
        at org.springframework.aop.framework.CglibAopProxy$CglibMethodInvocation.invokeJoinpoint(CglibAopProxy.java:736)
        at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:157)
        at org.springframework.transaction.interceptor.TransactionInterceptor$1.proceedWithInvocation(TransactionInterceptor.java:99)
        at org.springframework.transaction.interceptor.TransactionAspectSupport.invokeWithinTransaction(TransactionAspectSupport.java:282)
        at org.springframework.transaction.interceptor.TransactionInterceptor.invoke(TransactionInterceptor.java:96)
        at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:179)
        at org.springframework.aop.framework.CglibAopProxy$DynamicAdvisedInterceptor.intercept(CglibAopProxy.java:671)
        at com.kingdee.finance.data.credit.ydreport.service.impl.YdCreditAppendixInfoHandler$$EnhancerBySpringCGLIB$$e0cc861a.handleAppendixRequest(<generated>)
        at com.kingdee.finance.data.credit.ydreport.task.YdReportAppendixInfoTask.handleAppendixInfoTask(YdReportAppendixInfoTask.java:56)
        at com.kingdee.finance.data.credit.ydreport.task.YdReportAppendixInfoTask.run(YdReportAppendixInfoTask.java:43)
        at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
        at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
        at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
        at java.lang.reflect.Method.invoke(Method.java:497)
        at org.springframework.util.MethodInvoker.invoke(MethodInvoker.java:265)
        at org.springframework.scheduling.quartz.MethodInvokingJobDetailFactoryBean$MethodInvokingJob.executeInternal(MethodInvokingJobDetailFactoryBean.java:257)
        ... 3 more
    

    2、根据OOM堆栈错误日志,去扫了一眼代码并未看出什么问题。既然代码没有明显的内存泄露迹象,只能把目光转向堆内存对象分析了。

    3、从服务器上导出堆内存溢出的dump文件,用mat 打开分析一波。
    mat打开dump文件
    可以看到一个StringBuffer占了400M,另一个String对象占了224M,堆内存溢出跟这两个对象脱不了干系。搜索了下代码发现项目中出现问题的地方并没有用到StringBuffer这个类,应该是某个jar里有引用到的。点击String对象,看看value。
    查看String的Value

    4、根据String 对象的值,推测这是一个json格式的参数。用“username”和“businessNumber” 在代码中搜索。
    代码1
    这段代码就是组装请求参数,上面224M的String对象就是由这段代码产生。但出现400M的StringBuffer对象才是导致OOM的元凶,需要继续追查。
    代码2
    代码3
    代码4
    代码5
    整理出代码的调用关系,packRequestJson —> sendRequest —> HttpConnection.httpPostWithJSON —> URLEncoder.encode。很显然StringBuffer对象是由jar包中的URLEncoder.encode 方法中产生,这也跟日志中的堆栈日志正好也能对应上。
    日志

    三、问题原因
    根据上面分析以及查看代码,得知定时任务一次拉取 300条记录批次处理,组装参数得到一个224M 大小的String对象,然后在HTTP请求发送之前经过 URLEncoder.encode 方法 产生了一个400M大小的StringBuffer,直接导致了“java.lang.OutOfMemoryError” 异常。

    四、解决方案
    400M的大对象是由于一次取出300条记录,参数拼接生成的。可以将批处理记录数调小一点,就可以解决问题,批处理记录数应从数据配置中获取。

    四、总结
    1、线上异常预警,首先要查看项目日志。根据错误日志,来判断问题出现原因。确定好问题排查方向再选择相应的工具进行分析,多角度的观察,抽丝剥茧,直到找到问题的根源。

    2、问题排查要熟悉Java应用排查问题常用工具,比如:jstack、jmap、jps。
    查看某个应用的进程id以及启动参数:jps -v | grep “xxx”
    dump堆内存:jmap -dump:live,format=b,file=/heapdump.hprof {pid}
    导出线程栈:jstack {pid} > /jstack.txt

    展开全文
  • 记一次线上OOM 问题排查过程!

    千次阅读 2019-09-08 11:00:00
    公众号后台回复“学习”,获取作者独家秘制精品资料扫描下方海报二维码,试听课程:上周运维反馈线上程序出现了OOM,程序日志中的输出为Exception inthread ...

    公众号后台回复“学习”,获取作者独家秘制精品资料

    640?wx_fmt=png

    640?wx_fmt=jpeg

    扫描下方海报二维码,试听课程:

    640?wx_fmt=jpeg

    640?wx_fmt=png

    上周运维反馈线上程序出现了OOM,程序日志中的输出为

    Exception in thread "http-nio-8080-exec-1027" java.lang.OutOfMemoryError: Java heap space
    Exception in thread "http-nio-8080-exec-1031" java.lang.OutOfMemoryError: Java heap space	
    

    看线程名称应该是tomcat的nio工作线程,线程在处理程序的时候因为无法在堆中分配更多内存出现了OOM

    幸好JVM启动参数配置了-XX:+HeapDumpOnOutOfMemoryError,使用MAT打开拿到的hprof文件进行分析。

    第一步就是打开Histogram看看占用内存最大的是什么对象:

    640?wx_fmt=png

    可以看到byte数组占用了接近JVM配置的最大堆的大小也就是8GB,显然这是OOM的原因。

    第二步看一下究竟是哪些byte数组,数组是啥内容:

    640?wx_fmt=png

    可以看到很明显这和HTTP请求相关,一个数组大概是10M的大小。

    第三步通过查看GC根查看谁持有了数组的引用:

    640?wx_fmt=png

    这符合之前的猜测,是tomcat的线程在处理过程中分配了10M的buffer在堆上。

    至此,马上可以想到一定是什么参数设置的不合理导致了这种情况,一般而言tomcat不可能为每一个请求分配如此大的buffer。

    第四步就是检查代码里是否有tomcat或服务器相关配置,看到有这么一个配置:

    
     

    至此,基本已经确定了八九不离十就是这个不合理的最大http请求头参数导致的问题。

    到这里还有3个疑问:

    1. 即使一个请求分配10M内存,堆有8GB,难道当时有这么多并发吗?800个tomcat线程?

    2. 参数只是设置了最大请求头10M,为什么tomcat就会一次性分配这么大的buffer呢?

    3. 为什么会有如此多的tomcat线程?感觉程序没这么多并发。

    先来看问题1,这个可以通过MAT在dump中继续寻找答案。

    可以打开线程视图,搜索一下tomcat的工作线程,发现线程数量的确很多有401个,但是也只是800的一半:

    640?wx_fmt=png

    再回到那些大数组的清单,按照堆分配大小排序,往下看:

    640?wx_fmt=png

    可以发现除了有10008192字节的数组还有10000000字节的数组,查看引用路径可以看到这个正好是10M的数组是output buffer,区别于之前看到的input buffer:

    640?wx_fmt=png

    好吧,这就对了,一个线程分配了输入输出两个buffer,占用20M内存,一共401个线程,占用8GB,所以OOM了。还引申出一个问题:为啥有这么多工作线程!

    再来看看问题2,这就需要来找一下源码了,首先max-http-header-size是springboot定义的参数,查看springboot代码,可以看到这个参数对于tomcat设置的是MaxHttpHeaderSize:

    640?wx_fmt=png

    然后来看看tomcat源码:

    640?wx_fmt=png

    进一步看一下input buffer:

    640?wx_fmt=png

    buffer大小是MaxHttpHeaderSize+ReadBuffer大小,后者默认是8192字节:

    <attribute name="socket.appReadBufSize" required="false">
            <p>(int)Each connection that is opened up in Tomcat get associated with
            a read ByteBuffer. This attribute controls the size of this buffer. By
            default this read buffer is sized at <code>8192</code> bytes. For lower
            concurrency, you can increase this to buffer more data. For an extreme
            amount of keep alive connections, decrease this number or increase your
            heap size.</p>
          </attribute>

    这也就是为什么之前看到大量的buffer是10008192字节的。显然还有一批内容是空的10000000字节的buffer应该是output buffer

    来看看源码:

    640?wx_fmt=png

    这是一个header buffer,所以正好是10000000字节。

    至于问题3,显然我们的应用程序是配置过最大线程的(查看配置后发现的确,我们配置为了2000,好吧有点大),否则也不会有401个工作线程(默认150)

    如果当时并发并不大的话就一种可能,请求很慢,虽然并发不大,但是因为请求执行的慢就需要更多线程,比如TPS是100,但是平均RT是4s的话,就是400线程了。

    这个问题的答案还是可以通过MAT去找,随便看几个线程可以发现很多线程都在等待一个外部服务的返回,这说明外部服务比较慢

    然后去搜索当时的程序日志,可以发现有很多"feign.RetryableException: Read timed out executing的日志"。。。追杀下游去!慢点,我们的feign的timeout也需要再去设置一下,别被外部服务拖死了。

    END

    如有收获,请划至底部,点击“在看”,谢

    640?wx_fmt=png

    欢迎长按下图关注公众号石杉的架构笔记

    640?wx_fmt=jpeg

    BAT架构经验倾囊相授

    展开全文
  • Redis OOM问题排查

    千次阅读 2019-11-16 11:50:02
    看到Redis报了OOM的错误,而且服务响应速度非常慢,页面上丢了很多数据,赶紧起来查看问题。 2. 问题排查 我们的系统架构是双边双活的,两个DC(Primary和GSB)都会有数据写进来,通过API把数据存到数据库(双边...
  • 线上服务OOM问题排查

    2020-10-29 18:13:21
    问题描述 node2 服务异常,日志报错: java.lang.OutOfMemoryError: Java heap space (对外风控服务正常,因为node1服务正常,负载均衡服务会自动剔除异常节点) 排查过程 由于 JVM的启动参数没有显示指定.....
  • 容器OOM问题排查思路

    千次阅读 2018-11-26 21:52:19
    序言 又是一个冬季,在这寒冷的冬季,总是让人心动。。。迷雾之城 外界的刁难,挑战。。。其实并不是最难的,最难的总是内部难以安抚,OOM。。。内存泄漏,OOM ...
  • 一次OOM问题排查

    2018-01-18 17:39:16
    问题描述 用户问题:用户发现自己...经过我们的排查,发现cpu的两次间歇飙高是由于客户系统当时发生了OOM(out of memory)的情况,并触发了oom-killer造成的。但客户并不接受这个结论,认为是云服务器的异常导致了c...
  • 常见的问题排查方式 查看服务的进程是否存在 ps -ef | grep 服务名 ps -aux | grep 服务名 查看服务的日志 cat -n xxx_log |grep "OutOfMemoryError" java.lang.OutOfMemoryError GC overhead limit exceeded ...
  • OOM问题排查及原因解析

    千次阅读 2019-11-06 16:31:11
    现在才意识到,该机器是跑mq脚本的固定机器,由于进程开的太多导致内存占用太大,导致内存不够从而发生OOM kill问题。 二、深入理解OOM 2.1 Linux OverCommit Linux下允许程序申请比系统可用内存更多的内存...
  • 出现OOM问题后, 我们如何排查问题的出现点呢? 在这篇博客中我只是简单的说下如何排查问题的。 找到问题进程ID 第一步都是确定你的服务的进程id,有两种linux指令使用, top命令 使用top -c 会列出当前的进程列表: ...
  • $ top #或ps $ pmap 上面3步可以用工具bcc包中的memleak分析 $ memleak -a -p $(pidof app) #已知进程号情况下,或者直接 $memleak -a 2、内存泄露最终通过OOM释放 #查看OOM的进程 $ grep "Out of memory" /var/log/...
  • Java OOM 问题排查

    2020-12-18 14:23:38
    去代码中查看此处代码问题 二、可以使用 1、IBM heapAnalyzer 分析内存泄露的原因 下载地址:https://www.ibm.com/support/pages/ibm-heapanalyzer 桌面上创建一个.bat文件,文本内容为,定位到jar的目录地址 cd C...
  • OOM问题排查

    2019-10-10 17:46:19
    监控工具jvisualvm使用: jdk/bin 运行jvisualvm ps aux |more 详细信息包含cpu,内存 ps -mp pid -o THREAD,tid,time | sort -k2r 查看指定进程中各个线程占用CPU的状态,选出耗时最多、最繁忙的线程id ...
  • java OOM问题排查

    万次阅读 2014-11-14 18:05:36
    在做服务器端开发的时候,经常会遇到服务由于内存溢出挂掉的情况,这种情况的发生一般来说是很难预期的,也比较难以重现,对于这种问题,一般可以通过记录内存溢出时候的堆信息来排查。   1、首先可以查看服务器...
  • OOM排查思路

    千次阅读 2021-05-19 17:35:09
    什么是OOM 简单来说,就是程序的内存不够了,挂掉了 OOM的原因 oom的原因其实就一个,内存不够了,我们要细分的就是哪里的内存不够了,以及为什么内存不够了 栈溢出 这种情况属实比较少,一般就是栈调用太深了,比如...
  • Java OOM问题如何排查

    2021-11-08 17:22:24
    Java OOM问题如何排查 - 南山饱虎 - 博客园
  • 记一次OOM问题排查过程发布时间:2019-05-01 20:05,浏览次数:459, 标签:OOM上周运维反馈线上程序出现了OOM,程序日志中的输出为Exception in thread ...
  • 文章目录PreCase初步分析内存快照功夫在诗外:问题在JVM参数上分析一下JVM的GC日志分析一下JVM运行时内存使用模型优化第一步:增加堆内存大小优化第二步:改写代码总结 Pre 今天的案例背景是一个每天10亿数据量的...
  • 一次生产OOM问题排查

    2020-05-23 17:48:39
    我们有一个生产服务,规模是12台机器*6个节点 = 72个节点的服务,最近老是出现某个节点突然挂掉的情况,问题出现频繁,一天需要重启很多个节点 查看tomcat日志,发现是堆内存溢出 使用jmap -heap pid查看各个JVM内存...
  • 经过我们的排查,发现cpu的两次间歇飙高是由于客户系统当时发生了OOM(out of memory)的情况,并触发了oom-killer造成的。但客户并不接受这个结论,认为是云服务器的异常导致了cpu飙高,而cpu的升高又导致了oom情况的...

空空如也

空空如也

1 2 3 4 5 ... 20
收藏数 14,823
精华内容 5,929
关键字:

oom问题排查

友情链接: Inverter codes.rar