哪个Java线程消耗了我的CPU?

当您的Java应用程序占用100%的CPU时,您该怎么办? 事实证明,您可以使用内置的UNIX和JDK工具轻松找到有问题的线程。 不需要探查器或代理。

为了进行测试,我们将使用以下简单程序:

public class Main {public static void main(String[] args) {new Thread(new Idle(), 'Idle').start();new Thread(new Busy(), 'Busy').start();}
}class Idle implements Runnable {@Overridepublic void run() {try {TimeUnit.HOURS.sleep(1);} catch (InterruptedException e) {}}
}class Busy implements Runnable {@Overridepublic void run() {while(true) {'Foo'.matches('F.*');}}
}

如您所见,它启动了两个线程。 Idle不消耗任何CPU(请记住,睡眠线程消耗内存,但不消耗CPU),而Busy占用整个内核,因为正则表达式的解析和执行是一个令人惊讶的复杂过程。 让我们运行该程序,然后将其忽略。 我们如何快速发现Busy是我们软件中有问题的部分? 首先,我们使用top来找出消耗大部分CPU的java进程的进程ID( PID )。 这很简单:

$ top -n1 | grep -m1 java

这将显示包含“ java ”语句的top输出的第一行:

22614 tomek     20   0 1360m 734m  31m S    6 24.3   7:36.59 java

第一列是PID,让我们提取它。 不幸的是,事实证明top使用ANSI转义码表示颜色 –看不见的字符破坏了grepcut类的工具。 幸运的是,我找到了一个Perl脚本来删除这些字符 ,并最终能够提取用尽CPU的java进程的PID:

$ top -n1 | grep -m1 java | perl -pe 's/\e\[?.*?[\@-~] ?//g' | cut -f1 -d' '

cut -f1 -d' '调用只是将第一个值从以空格分隔的列中取出:

22614

现在,当我们遇到有问题的JVM PID时,我们可以使用top -H查找有问题的Linux线程。 -H选项显示与进程相对的所有线程的列表,PID列现在表示内部Linux线程ID:

$ top -n1 -H | grep -m1 java
$ top -n1 -H | grep -m1 java | perl -pe 's/\e\[?.*?[\@-~] ?//g' | cut -f1 -d' '

输出令人惊讶地相似,但是第一个值现在是线程ID:

25938 tomek     20   0 1360m 748m  31m S    2 24.8   0:15.15 java
25938

因此,我们有一个繁忙的JVM的进程ID和Linux线程ID(很可能来自该进程)消耗了我们的CPU。 这是最好的部分:如果查看jstack输出(在JDK中可用),则每个线程的名称旁边都会印有一些神秘的ID:

'Busy' prio=10 tid=0x7f3bf800 nid=0x6552 runnable [0x7f25c000]java.lang.Thread.State: RUNNABLEat java.util.regex.Pattern$Node.study(Pattern.java:3010)

没错, nid=0x645a参数与top -H打印的线程ID相同。 当然,不要太简单,在jstack以十六进制打印时, top使用十进制表示法。 再次有一个简单的解决方案, printf'%x' :

$ printf '%x' 25938
6552

让我们将我们现在拥有的所有内容包装到一个脚本中并合并结果:

#!/bin/bash
PID=$(top -n1 | grep -m1 java | perl -pe 's/\e\[?.*?[\@-~] ?//g' | cut -f1 -d' ')
NID=$(printf '%x' $(top -n1 -H | grep -m1 java | perl -pe 's/\e\[?.*?[\@-~] ?//g' | cut -f1 -d' '))
jstack $PID | grep -A500 $NID | grep -m1 '^$' -B 500

PID持有java PID, NID持有线程ID,很可能来自该JVM。 最后一行只是转储给定PID的JVM堆栈跟踪,并过滤(使用grep )具有相匹配的nid的线程。 猜猜它有什么用:

$ ./profile.sh
'Busy' prio=10 tid=0x7f3bf800 nid=0x6552 runnable [0x7f25c000]java.lang.Thread.State: RUNNABLEat java.util.regex.Pattern$Node.study(Pattern.java:3010)at java.util.regex.Pattern$Curly.study(Pattern.java:3854)at java.util.regex.Pattern$CharProperty.study(Pattern.java:3355)at java.util.regex.Pattern$Start.<init>(Pattern.java:3044)at java.util.regex.Pattern.compile(Pattern.java:1480)at java.util.regex.Pattern.<init>(Pattern.java:1133)at java.util.regex.Pattern.compile(Pattern.java:823)at java.util.regex.Pattern.matches(Pattern.java:928)at java.lang.String.matches(String.java:2090)at com.blogspot.nurkiewicz.Busy.run(Main.java:27)at java.lang.Thread.run(Thread.java:662)

多次运行脚本(或使用watch ,请参见下文)将在不同位置捕获Busy线程,但是几乎总是在正则表达式解析中进行–这是我们有问题的部分!

多线程

如果您的应用程序具有多个需要CPU的线程,则可以使用watch -n1 ./profile.sh命令watch -n1 ./profile.sh运行一次脚本并获取半实时堆栈转储,这很可能来自不同的线程。 使用以下程序进行测试:

new Thread(new Idle(), 'Idle').start();
new Thread(new Busy(), 'Busy-1').start();
new Thread(new Busy(), 'Busy-2').start();

您将看到Busy-1Busy-2线程的堆栈跟踪(在Pattern类中的不同位置),但是从不Idle

参考: 哪个Java线程消耗了我的CPU? 来自我们的JCG合作伙伴 Tomasz Nurkiewicz,来自Java和邻里博客。


翻译自: https://www.javacodegeeks.com/2012/08/which-java-thread-consumes-my-cpu.html

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/371383.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

烟草局计算机笔试,2020年广西南宁烟草局什么时候笔试?

最近广西烟草局各地市社招通知频发&#xff0c;南宁烟草局报名截止至今都无任何消息&#xff0c;根据往年的考情&#xff0c;通知近期很大可能会发布&#xff0c;将于6月底完成笔面!你备考好了吗&#xff1f;今天广西中公国企小编来给大家说一下南宁烟草局社招的笔试内容及备考…

JAVA Swing 组件演示***

下面是Swing组件的演示&#xff1a; package a_swing;import java.awt.BorderLayout; import java.awt.Color; import java.awt.Container; import java.awt.Cursor; import java.awt.Dimension; import java.awt.GridLayout; import java.awt.event.ActionEvent; import java.…

Spring 3.1缓存和@CacheEvict

我的上一个博客演示了Spring 3.1的Cacheable批注的应用&#xff0c; Cacheable批注用于标记返回值将存储在缓存中的方法。 但是&#xff0c; Cacheable只是Spring的Guy为缓存而设计的一对注释​​中的一个&#xff0c;另一个是CacheEvict 。 像Cacheable一样&#xff0c; Cache…

centos 获取硬件序列号_如何在 Linux 上查找硬件规格

在 Linux 系统上有许多工具可用于查找硬件规格。-- Sk&#xff08;作者&#xff09;在 Linux 系统上有许多工具可用于查找硬件规格。在这里&#xff0c;我列出了四种最常用的工具&#xff0c;可以获取 Linux 系统的几乎所有硬件&#xff08;和软件&#xff09;细节。好在是这些…

位置服务器管理器,查看 DIMM 位置

键入&#xff1a;-> show /System/Memory/DIMMs -t locationTarget | Property | Value-----------------------------------------------------------------------/System/Memory/DIMMs/ | location | CMIOU0/CM/CMP/BOB00/CH0/DIMM (CPU MemoryDIMM_0 | | IO Unit 0 Memor…

Spring –持久层–编写实体并配置Hibernate

欢迎来到本教程的第二部分。 当您看到本文有多长时间时&#xff0c;请不要惊慌–我向您保证&#xff0c;这主要是简单的POJO和一些生成的代码。 在开始之前&#xff0c;我们需要更新我们的Maven依赖项&#xff0c;因为我们现在将使用Hibernate和Spring。 将以下依赖项添加到pom…

无线服务器主机名是,wifi默认服务器主机名

wifi默认服务器主机名 内容精选换一换以CentOS 7操作系统的弹性云服务器为例&#xff1a;登录Linux弹性云服务器&#xff0c;查看“cloud-init”的配置文件。检查“/etc/cloud/cloud.cfg”文件中“update_hostname”是否被注释或者删除。如果没有被注释或者删除&#xff0c;则需…

pygame里面物体闪烁运动_利用自闪烁发光二极管探究小车在倾斜轨道上的运动规律...

2020年11月23日&#xff0c;周一&#xff0c;24小时安全值班。利用当班中午的时间&#xff0c;微主在创客空间测试了自闪烁发光二极管在匀加速运动中的效果&#xff0c;结果还比较满意。将小车放置在倾斜的轨道上&#xff0c;将自闪烁发光二极管和纽扣电池构成频闪光源&#xf…

python网络爬虫与信息提取 学习笔记day3

Day3&#xff1a; 只需两行代码解析html或xml信息 具体代码实现:day3_1 注意BeautifulSoup的B和S需要大写&#xff0c;因为python大小写敏感 import requests r requests.get("http://python123.io/ws/demo.html") r.text demo r.text from bs4 import Beauti…

番石榴文件:Java文件管理

正如我在这里 &#xff0c; 这里 &#xff0c; 这里和这里所讨论的那样&#xff0c; Groovy和Java SE 7都为Java文件管理提供了改进。 但是&#xff0c;当特定的Java应用程序尚不能使用Java SE 7或Groovy进行文件管理时&#xff0c;仍然可以通过使用Guava的Files类获得改进的文…

顺序查找

顺序查找属于查找中较容易的一个方法&#xff0c;且对数据是否已经排序没有要求&#xff0c;是很常用的一个查找算法。 但缺点是必须一个一个数字进行比较查找&#xff0c;查找所需步骤可能较多。 顺序查找算法的思想是&#xff0c;将目标与待查找数据进行比较&#xff0c;若发…

王者荣耀微信哪个服务器人最少,王者荣耀:微信区王者人数锐减,大神们都去哪了?这些原因很真实...

原标题&#xff1a;王者荣耀&#xff1a;微信区王者人数锐减&#xff0c;大神们都去哪了&#xff1f;这些原因很真实王者荣耀&#xff1a;微信区王者人数锐减&#xff0c;大神们都去哪了&#xff1f;这些原因很真实大家好&#xff01;王者荣耀S16赛季已经开启一月之余&#xff…

一个div压在另一个div上面_【CSS小分享】用CSS画一个新拟态风格键盘

什么是新拟态新拟态的英文名称是“Neumorphism”&#xff0c;也有人称为“Soft UI”。简单讲&#xff0c;新拟态是一种图形样式&#xff0c;其原理是通过模拟真实物体来为界面的UI元素赋予真实感。新拟态风格起源于dribbble&#xff0c;后面陆续被收录在2020设计趋势预测里面&a…

JBoss BRMS与JasperReports进行报告

介绍 Jasperreports是一个免费的可下载库&#xff0c;可用于为Java EE应用程序生成丰富的报告。 本指南还提供了使用Jasper iReport设计器生成报告模板的步骤。 软件需求 JBoss BRMS 5.3&#xff08;从客户门户网站http://access.redhat.com &#xff09; JasperReports 4.6…

java字符串 删除指定字符的那些事

需求如下&#xff1a; 1.算出2周以前的时间&#xff0c;以正常日期格式返回 2.如果月份和日期前面有0需要去掉返回结果&#xff0c;比如&#xff1a;2017-08-15 就需要显示2017-8-15。 Calendar calendar Calendar.getInstance();calendar.add(Calendar.DATE, -14);Date date…

Hibernate中Hql查询

这篇随笔将会记录hql的常用的查询语句&#xff0c;为日后查看提供便利。 在这里通过定义了三个类&#xff0c;Special、Classroom、Student来做测试&#xff0c;Special与Classroom是一对多&#xff0c;Classroom与Student是一对多的关系&#xff0c;这里仅仅贴出这三个bean的属…

Java代码质量工具–概述

最近&#xff0c;我有机会在本地IT社区聚会上介绍了该主题。 这是基本演示&#xff1a; Java代码质量工具 以及更有意义的思维导图&#xff1a; 但是&#xff0c;我认为我需要更深入地探讨这一主题。 这篇博客文章应该像是在此方向上进行进一步调查的起点。 1. CodePro Anal…

利用yum升级Centos6的gcc版本,使其支持C++11

下面的可以在centos6下工作&#xff0c;centos7下有问题。可能是因为centos下的scl我是拷贝的文件&#xff0c;没有完全验证centos6下肯定没问题。 https://my.oschina.net/u/583362/blog/682123 和https://www.quyu.net/info/876.html 拷贝其关键内容就是&#xff1a; 1.使用 …

cuda版本查看_ubuntu安装CUDA

0 写在前面安装环境&#xff1a;ubuntu18.04以及GTX1050Ti笔记本为什么要安装CUDA&#xff1f; 参考百科&#xff0c;CUDA是英伟达推出的集成技术&#xff0c;通过该技术可利用GeForce 8 以后的GPU或者较新的Quadro GPU进行计算。例如典型的tensorflow-GPU和pyCUDA安装之前都要…

HTML 标签列表(功能排序) HTML 参考手册- (HTML5 标准)

HTML 标签列表&#xff08;功能排序&#xff09; HTML 参考手册- (HTML5 标准) 功能排序 New : HTML5 新标签 标签描述基础 <!DOCTYPE> 定义文档类型。<html>定义一个 HTML 文档<title>为文档定义一个标题<body>定义文档的主体<h1> to <h6>…