JAVA进程占用CPU200%-300%的问题处理过程

故事背景

今天后台管理系统出现cpu 200%-300%,导致总CPU使用忽高忽低,系统访问速度忽快忽慢。这个问题出现过一次,准备排查一下。
后台管理系统使用ssm框架,用户量小,所以排除高并发的情况。

java version "1.8.0_11"

处理过程

1.使用top查看进程的CPU使用情况

[root logs]# top
top - 14:34:51 up 513 days,  4:42,  3 users,  load average: 3.27, 2.81, 2.34
Tasks: 147 total,   1 running, 146 sleeping,   0 stopped,   0 zombie
Cpu(s): 59.8%us,  0.2%sy,  0.0%ni, 40.0%id,  0.0%wa,  0.0%hi,  0.1%si,  0.0%st
Mem:  16270528k total, 10517928k used,  5752600k free,   178872k buffers
Swap:        0k total,        0k used,        0k free,  1333952k cached

  PID USER      PR  NI  VIRT  RES  SHR S %CPU %MEM    TIME+  COMMAND                                                                                                                                    
15984 root      20   0 7867m 3.9g  18m S 235.5 25.0 929:15.66 java                                                                                                                                       
16102 root      20   0 7860m 3.9g  14m S  4.3 24.9 743:39.72 java                                                                                                                                        
21631 root      20   0 15032 1276  944 R  0.3  0.0   0:00.06 top                                                                                                                                         
    1 root      20   0 19368 1232  912 S  0.0  0.0   0:01.55 init      

可以看到是pid为15984的进程占用了CPU。
先用jstat -gcutil (查看GC汇总信息),看下对应的堆内存各部分的使用量

[root@ logs]# jstat -gcutil 15984
  S0     S1     E      O      M     CCS    YGC     YGCT    FGC    FGCT     GCT   
  0.00   0.00 100.00 100.00  55.48  79.70  72824 1046.497  1339 3559.981 4606.479

显示列名具体描述
S0年轻代中第一个survivor(幸存区)已使用的占当前容量百分比
S1年轻代中第二个survivor(幸存区)已使用的占当前容量百分比
E年轻代中Eden(伊甸园)已使用的占当前容量百分比
Oold代已使用的占当前容量百分比
M元数据空间使用比例
CCS压缩使用比例
YGC从应用程序启动到采样时年轻代中gc次数
YGCT从应用程序启动到采样时年轻代中gc所用时间(s)
FGC从应用程序启动到采样时old代(全gc)gc次数
FGCT从应用程序启动到采样时old代(全gc)gc所用时间(s)
GCT从应用程序启动到采样时gc用的总时间(s)

可以看到
年轻代Eden区和老年代的使用容量都是100%

补充个知识点:
大多数情况下,对象在新生代Eden区分配。(大对象会直接在老年代分配,使用参数进行设置)当Eden区分配足够的空间进行分配时,就会触发MinorGc(新生代GC)。将超过GC年龄的对象移动到老年代中。

大致就能断定是对象Eden区分配内存时容量不够触发了GC,而导致的GC停顿。但是由于新生代和老年代的使用都是100%而对象又全都在被使用。所以无法回收内存。导致一直GC,一直停顿。。。
问题找到了,这没办法了。直接重启服务,毕竟没有什么是重启不能解决的,但是在重启之前先做一件事情。把堆内存的快照dump下来,找找为什么4G的内存都被用完了,还无法回收。。。

使用 jmap -dump:live 生成快照
jmap -dump:live,format=b,file=15984.hprof 15984
使用scp 远程上传文件到跳板机

下载到本地只用使用java/bin/jvisualvm.exe 工具打开。可以进行快照文件的分析…
文件 > 装入 >选择下载的堆内存快照。
内存快照大的会需要很大的内存才能打开…我的快照文件3.7G,装入之后大概使用了7G内存。
在这里插入图片描述
因为堆内存太大,自己电脑的配置太小了,所以找了台内存大的电脑弄。结果堆内存太大导致看到了类信息之后想打开实例信息没成功。提示分析工具的内存不足…我太难了…
在这里插入图片描述

原因分析

看了一些网上的帖子和项目组种种分析得到的结论大概率是因为tomcat间的session共享导致的session没有回收。

项目用了两个tomcat,配置了tomcat自身session共享机制,但是由于配置的是双向共享。所以session永远都不会清掉。。。导致了session占用的内存越来越多。
因为上次出现这个问题也是加入session共享之后出现的,而且出现问题时系统session存活的数量也差不多。所以有了这种猜想。。

解决方案

就把seesion共享改成单方式的试试。
…还在弄,目前不知道怎么整单方向的共享方式…
…我太难了…

  • 1
    点赞
  • 10
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
如果Java进程CPU占用率较高,可能有多种原因,以下是一些常见的排除步骤: 1. 确认Java版本:首先,您应该确认Java版本是否与应用程序或框架的要求相符。Java版本过低或过高可能导致CPU占用率过高。 2. 确认应用程序是否有异常行为:检查应用程序的日志文件和监视控制台输出,以查找异常行为,如无限循环、内存泄漏、线程阻塞等。这些异常行为可能导致CPU占用率过高。 3. 分析堆栈信息:通过分析Java堆栈信息,可以确定哪些线程正在运行以及正在执行哪些代码。您可以使用Java虚拟机自带的工具,如jstack和jmap,来获取和分析堆栈信息。 4. 监视系统资源:您可以使用操作系统自带的工具,如top(Linux)和Task Manager(Windows),来监视系统资源的使用情况。如果CPU使用率过高,您可以检查哪些进程正在使用大量CPU资源。 5. 调整Java虚拟机参数:通过调整Java虚拟机参数,可以优化应用程序的性能。例如,您可以调整垃圾收集器的参数,以减少垃圾回收时间和频率。您可以使用Java虚拟机自带的工具,如jstat和jconsole,来监视和调整Java虚拟机参数。 6. 升级硬件:如果CPU占用率过高且无法通过优化Java虚拟机参数来解决,您可以考虑升级硬件,如添加更多的CPU或内存。 以上是一些常见的排除步骤,您可以根据具体情况选择相应的方法。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值