快捷搜索: 王者荣耀 脱发

Java实践总结:高CPU占用问题

高CPU占用问题

生产环境下的某台Java语言开发的服务器,在刚发布时的时候一切都很正常,在运行一段时间后就出现CPU占用很高的问题,基本上是负载一天比一天高。 针对这一问题,如何定位引起高CPU占用原因?

方法一:逐条命令洞玄机

1.使用top命令 定位到占用CPU高的进程PID 2.获取线程信息,并找到占用CPU高的线程 ps -mp pid -o THREAD,tid,time | sort -rn

3.将需要的线程ID转换为16进制格式 printf "%x " tid

4.打印线程的堆栈信息,定位到引起CPU高的代码 jstack pid |grep tid -A 30

方法二:快捷脚本提效率

通过阿里天猫事业部李鼎贡献的脚本定位CPU问题,事半功倍。访问地址:

  1. 用于快速排查Java的CPU性能问题(top us值过高),自动查出运行的Java进程中消耗CPU多的线程,并打印出其线程栈,从而确定导致性能问题的方法调用。
  2. 找出jar文件和class目录中的重复类。用于排查Java类冲突问题。
  3. 在目录下所有jar文件里,查找类或资源文件。
?

Shell使用加强:

  1. 原样命令行输出,并拷贝标准输出到系统剪贴板,省去CTRL+C操作,优化命令行与其它应用之间的操作流。
  2. 彩色cat出文件行,方便人眼区分不同的行。
  3. 按行彩色输出参数,方便人眼查看。
  4. 批量转换文件路径为绝对路径/相对路径,会自动跟踪链接并规范化路径。
  5. 统计各个TCP连接状态的个数。用于方便排查系统连接负荷问题。
  6. 在命令行中快速完成 在文件浏览器中 打开/选中 指定的文件或文件夹的操作,优化命令行与其它应用之间的操作流。

Shell开发/测试加强:

  1. 输出脚本收到的参数,在控制台运行时,把参数值括起的括号显示成 红色,方便人眼查看。用于调试脚本参数输入。
  2. 显示Terminator的全部文字彩色组合的效果及其打印方式,用于开发Shell的彩色输出。
  3. 命令行选项解析库,加强支持选项有多个值(即数组)。

其中,show-busy-java-threads脚本用于定位java线程中占用CPU最高的TopN线程,并打印堆栈信息,将方法一的过程包装了起来。 使用方法 bash show-busy-java-threads.sh -p pid

Java占用CPU很高的可能原因

(1)一个应用占用CPU很高,除了确实是计算密集型应用之外,通常原因都是出现了死循环。死循环肯定要占用一个CPU不放,这是由于操作系统的机制原因造成的,其他原因也一样。 (2)空循环会造成间歇性的CPU高,最常见的场景是信息采集系统中使用while从消息队列(泛指,可以是文件系统、队列、kafka等)循环采集消息,当消息队列中有消息可供处理时,CPU表现正常,当如果消息队列中没有消息,while就会陷入空循环,短时间内CPU会飙升。 (3)由内存泄露引起的CPU狂飙。这类问题最难定位,一般在系统使用一段时间后才会发生,其现象表现为CPU高居不小,系统无法提供正常服务,最明显的标志是使用以上方法定位到的线程中存在大量GC相关的线程。这类问题产生的原因是程序中逻辑处理不当,导致堆内存无法及时回收,产生了大量的垃圾,JVM的GC开始疯狂工作导致其他进程的资源被耗尽。这类问题可从CPU和内存两个方面展开定位分析并予以解决。

经验分享 程序员 微信小程序 职场和发展