哪個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.pswp.cn/news/371383.shtml
繁體地址,請注明出處:http://hk.pswp.cn/news/371383.shtml
英文地址,請注明出處:http://en.pswp.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>…