一次服务器CPU占用率高的定位分析
现象: 当前项目启动一段时间,有一个服务导致CPU使用率持续超过30%
环境:Windows 7, CPU: 8核, 内存: 8g内存
定位过程:
启动项目,查看Java进程ID

查看Event Processor 的CPU使用情况,此时基本维持在1%左右:

开启Simulator发送几包数据,再次查看,发现CPU已经飚上去了:

关闭Simulator,等待数据都处理完毕,再次查看,CPU并未降下去:

使用ProcessExplorer查看Event Processor线程的CPU使用情况,发现线程40160和40156的CPU占用率持续很高,

使用jstack -l 35684 打印出Event Process的线程栈,查看线程ID(需转化成16进制)对应(40160-> 9CE0, 40156-> 9CDC)的线程栈:

可以看出,线程TaskScheduler_com.delta.atm.services.impl.AutoTTExecutorServiceImpl和TaskScheduler_com.delta.atm.services.impl.AlarmExecutorServiceImpl处于运行状态,持续打印线程信息发现这两个线程一直处于RUNNABLE的状态,此时并未开启simulator,此线程应该处于睡眠才对。
先走读代码,查看AlarmServiceImpl,

再查看SchedulerServiceImpl,

从下面代码的角度看,在没有数据的情况下takeTask应该只会执行一次,然后休眠,等待唤醒。

根据打印的线程栈发现,这两个线程都长时间运行在takeTask方法,所以猜测这个部分有死循环,而且由于此机器是8核,1/8=0.125,如果有两个线程持续While循环,则基本就会占用25%的CPU资源。

加上输出,打印出全局的count,找到原因了,线程睡眠的条件是count为0才睡眠,但是数据都处理完了打印出来的count不为0所以线程会一直空转,

但是为什么会出现数据处理完count还不为0的情况呢?

从代码结果来看alarmService每收到一包数据count就会加1,每取一包数据,count就会减1,而且count是AtomicInteger线程安全类型。
由于alarmService用的是一个生产者-消费者模型,大概结构如下图所示,需要一个全局的count来表示所有queue里面的数据,当count数量为0的时候Task Schedule则睡眠,否则会持续调度。


查看当前queue里面的数据是空的,说明queue里面的数据已经处理完了,但是count的值却不是0。
查看下面的代码找到原因,这个queue是我们自己封装的,每个site对应一个queue,key值是dataTime,这个值是根据印度的box取的且只有10位,精确到秒,但是simulator每个站点数据的发送频率经常会一秒钟发送多包数据,所以就会有重复的dataTime,也就造成了queue里面数据被覆盖了,这个时候queue的总大小就和记录的count不匹配了。

其实这个queue的内部我们使用的是一个treeMap,所以不允许key值重复,最好的办法是重写一个允许key值重复并且可排序的一个队列,但是考虑到现实环境中每个站点3分钟才发一包数据不可能出现每秒多包数据的情况,而且TreeMap内部用的是红黑树效率挺高的,如果自己写排序算法效率可能不会太好,所以暂时使用判断做规避,如果同一个站点queue里面已经有相同的dataTime则直接忽略这一包数据。

重新打包启动查看输出, count已经降下来了

查看CPU使用率如下

查看线程状态,已经处于waiting,问题解决。

一次服务器CPU占用率高的定位分析的更多相关文章
- Linux下java进程CPU占用率高分析方法
Linux下java进程CPU占用率高分析方法 在工作当中,肯定会遇到由代码所导致的高CPU耗用以及内存溢出的情况.这种情况发生时,我们怎么去找出原因并解决. 一般解决方法是通过top命令找出消耗资源 ...
- CPU占用率高分析方法步骤[转载]
由于涉及到私有代码,所有图片都隐去 1.执行TOP命令,确认CPU占用较高的进程PID 根据top命令,发现PID为8691的Java进程占用CPU高达3858%,出现故障 2.确认该进程中CPU占用 ...
- Linux下分析某个进程CPU占用率高的原因
Linux下分析某个进程CPU占用率高的原因 通过top命令找出消耗资源高的线程id,利用strace命令查看该线程所有系统调用 1.top 查到占用cpu高的进程pid 2.查看该pid的线程 ...
- Java CPU占用率高分析
首先,通过top命令找出CPU占用率高的进程: 然后,通过ps -o THREAD,tid,time -mp 2066命令找出执行时间最长的线程的TID 将有问题的TID转为16进制格式: print ...
- (转)Linux下java进程CPU占用率高-分析方法
Linux下java进程CPU占用率高-分析方法 原文:http://itindex.net/detail/47420-linux-java-%E8%BF%9B%E7%A8%8B?utm_source ...
- Linux下java进程CPU占用率高分析方法(一)
Linux下java进程CPU占用率高分析方法 在工作当中,肯定会遇到由代码所导致的高CPU耗用以及内存溢出的情况.这种情况发生时,我们怎么去找出原因并解决. 一般解决方法是通过top命令找出消耗资源 ...
- 查看Windows下引起Oracle CPU占用率高的神器-qslice
前言: qslice是一个win2000的工具包,能分析进程的cpu占用率,我们用于分析oracle的性能 这是绿色的软件无需安装. 我们经常会碰到oracle的CPU占用居高不下,无法快速定位到问题 ...
- 线上Java程序导致服务器CPU占用率过高的问题排除过程
博文转至:http://www.jianshu.com/p/3667157d63bb,博文更好效果看原版,转本博文的目的就算是个书签吧,需要时候可以定位原文学习 1.故障现象 客服同事反馈平台系统运行 ...
- 记一次线上Java程序导致服务器CPU占用率过高的问题排除过程
博文转至:http://www.jianshu.com/p/3667157d63bb,转本博文的目的就是需要的时候以防忘记 1.故障现象 客服同事反馈平台系统运行缓慢,网页卡顿严重,多次重启系统后问题 ...
随机推荐
- winform 禁用鼠标滚轮
新建一个类,继承IMessageFilter public class FormFilter : IMessageFilter { public bool PreFilterMessage(ref M ...
- android中listview的item滑动删除效果(已解决listview点击问题)
领导看到iphone上tableview有个滑动删除的效果,要求在android上也实现,搜了下资料,实现起来比较简单,可弄到后面,居然不能点击了,把一篇文章中的代码修改了一下,捣鼓了一番,搞定,下面 ...
- RabbitMQ PHP操作类,守护进程及相关测试数据
封装类如下: <?php /* * amqp协议操作类,可以访问rabbitMQ * 需先安装php_amqp扩展 */ class RabbitMQCommand{ public $confi ...
- source insight添加汇编文件.s
(1) 做ARM嵌入式开发时,有时得整汇编代码,但在SIS里建立PROJECT并ADD TREE的时候,根据默认设置并不会把该TREE里面所有汇编文件都包含进来,默认只加了.inc和.asm后缀的, ...
- OC - 正则表达式 - RegexKitLite
正则表达式使用步骤: 1. 创建正则表达式对象, 设置约束条件; NSString *pattern = @"\\d{1,3}"; NSRegularExpression *reg ...
- Sql server中DateDiff用法【转】
记录下来.每次使用都忘记.... DATEDIFF 函数 [日期和时间] 功能 返回两个日期之间的间隔. 语法 DATEDIFF ( date-part, date-expression-1, dat ...
- 转:Stack Overflow通过关注性能,实现单块应用架构的扩展能力
原文来自于:http://www.infoq.com/cn/news/2015/07/scaling-stack-overflow 在New York QCon 2015大会上,David Fulle ...
- ThinkPHP3.1快速入门(3)查询语言
http://www.thinkphp.cn/info/115.html 介绍 ThinkPHP内置了非常灵活的查询方法,可以快速的进行数据查询操作,查询条件可以用于读取.更新和删除等操作,主要涉及到 ...
- 【Xamarin 挖墙脚系列:IOS 开发界面的3种方式】
原文:[Xamarin 挖墙脚系列:IOS 开发界面的3种方式] xcode6进行三种基本的界面布局的方法,分别是手写UI,xib和storyboard.手写UI是最早进行UI界面布局的方法,优点是灵 ...
- 设置VS2015上关闭和打开tab快捷键
Ctrl+W关闭Tab: Tools > Options > Environment > Keyboard > File.Close > Use new shortcut ...