当应用系统出现卡顿或者应用程序响应速度非常慢的时候,我们需要登录到应用所在主机进行查看、分析问题原因。
使用${JAVA_HOME}/bin/jstat -gcutil PID 1000 10查看占用CPU资源较高的进程GC情况;
使用命令:top
可以看到PID为4267,USER为dform的进程CPU使用率高达1464.2%(即消耗当前主机14.64个CPU),严重超高。使用命令cat/proc/cpuinfo | grep processor |wc –l 可查看当前主机逻辑CPU个数。
使用命令:top-p 4267-H
红框标出的10几个线程耗用CPU都接近或者超过了100%(即该进程下有10几个线程耗用CPU都高达1个左右)。
使用命令:
连续导出多个线程栈(stack)快照文件,每次导出间隔5s-10s
${JAVA_HOME}/bin/jstack4267 > stack_4267_1.log
${JAVA_HOME}/bin/jstack4267 > stack_4267_2.log
${JAVA_HOME}/bin/jstack4267 > stack_4267_3.log
使用命令:我们选取如下两个线程为例
(1)线程PID4477,转换之后的十六进制nid为117d
printf "%x "4477
(2)线程PID4542,转换之后的十六进制nid为11be
(1)根据nid=0x117d查找到正在运行的程序代码模块,红框标出是该线程最后正在做的事物(线程执行顺序要从下向上看),绿框标出是应用侧代码模块。
(2)同理,根据nid=0x11be查找到正在运行的程序代码模块
最后将上述分析结果和线程栈(stack)快照文件一并反馈给应用侧核查和处理。
导致Java进程频繁FULLGC的原因有:
(1)应用代码逻辑设计不合理,对象创建太多,而且对象使用完后未及时释放资源,或者已不再有用的对象相互之间存在引用,导致该对象无法进行回收;
(2)消费者消费速度慢(或停止消费),而生产者不断往队列中投递任务,导致队列中任务累积过多,任务对象占用堆内存太多而产生FULLGC;
(3)应用进程创建线程太多(每个线程需要分配线程栈内存),也可能导致内存溢出OOM,触发FULLGC;
注:分析FULLGC的问题,除了要分析案例1中的线程栈(stack)快照信息外,还要导出JVM堆(heap)进行分析。
${JAVA_HOME}/bin/jmapdump:live,format=b,file=17074.hprof17074
注:堆(heap)快照文件一般都比较大,有几个G大小(基本和参数-Xmx设置大小一致)。
通过对堆内存快照文件17074.hprof的分析,发现有以下一些对象占用内存较多:
结合日志信息分析,应用一次性经过代理节点从数据节点中获取大量数据到堆内存中,并同时几条请求同时进行,该代理节点出现JVM堆内数据占用较大导致内存溢出,FULLGC无法回收,此后一直频繁FullGC。另根据GC信息分析,大约7个小时就会有一次较多请求刷新导致内存占用过多的情况。
最后将分析结果反馈给应用侧核查和处理。
文章版权归作者所有,未经允许请勿转载,若此文章存在违规行为,您可以联系管理员删除。
转载请注明本文地址:https://www.ucloud.cn/yun/130177.html
摘要:线程仅仅被视为一个与其他进程共享某些资源的进程。稳定性可创建的线程的数量上存在限制,包括的启动参数操作系统对线程的限制,如果超出这些限制,很可能会抛出异常。若是密集型程序产生大量的线程切换,将会降低系统的吞吐量。 OS中的进程、线程 进程:即处于执行期的程序,且包含其他资源,如打开的文件、挂起的信号、内核内部数据、处理器状态、内核地址空间、一个或多个执行的线程、数据段。 线程:进程中...
阅读 1346·2023-01-11 13:20
阅读 1684·2023-01-11 13:20
阅读 1132·2023-01-11 13:20
阅读 1858·2023-01-11 13:20
阅读 4100·2023-01-11 13:20
阅读 2704·2023-01-11 13:20
阅读 1385·2023-01-11 13:20
阅读 3597·2023-01-11 13:20