日本黄色一级经典视频|伊人久久精品视频|亚洲黄色色周成人视频九九九|av免费网址黄色小短片|黄色Av无码亚洲成年人|亚洲1区2区3区无码|真人黄片免费观看|无码一级小说欧美日免费三级|日韩中文字幕91在线看|精品久久久无码中文字幕边打电话

當(dāng)前位置:首頁 > > 21ic電子網(wǎng)
[導(dǎo)讀]1、CPU 使用率怎么計算? CPU% = (1 - idleTime / sysTime) * 100 idleTime:CPU處于空閑狀態(tài)的時間 sysTime:CPU處于用戶態(tài)和內(nèi)核臺的時間總和 2、CPU 使用率跟啥有關(guān)系? 常聽說計算密集型的程序是比較耗 CPU 使用率的。 3、CPU 與進程、線程有關(guān)系么? 現(xiàn)


1、CPU 使用率怎么計算?


CPU% = (1 - idleTime / sysTime) * 100

  • idleTime:CPU處于空閑狀態(tài)的時間

  • sysTime:CPU處于用戶態(tài)和內(nèi)核臺的時間總和


2、CPU 使用率跟啥有關(guān)系?


常聽說計算密集型的程序是比較耗 CPU 使用率的。


3、CPU 與進程、線程有關(guān)系么?


現(xiàn)在分時操作系統(tǒng)是通過循輪方式分配時間片進行進程調(diào)度的,如果進程在等待或阻塞,不會造成 CPU 資源使用。線程稱為輕進程,共享進程資源,關(guān)于線程的調(diào)度,CPU 對于線程也是分時調(diào)度。而在 Java 中,線程的調(diào)用由 JVM 負責(zé),線程的調(diào)度一般有兩種模式,分時調(diào)度和搶占式調(diào)度。



4、一個 while 死循環(huán),會不會引起 CPU 使用率飚升?


會的。


先不說別的,死循環(huán)會調(diào)用 CPU 寄存器進行計數(shù),這個操作就會占用 CPU。其次,如果線程一直處于死循環(huán)狀態(tài),CPU 調(diào)用會進行線程切換么?


死循環(huán)不會讓出 CPU,除非操作系統(tǒng)時間片到期,但死循環(huán)會不斷向系統(tǒng)申請時間片,直到系統(tǒng)沒有空閑時間做別的事情。


這個問題在 stackoverflow 也有人提問:why does an infinite loop of the unintended kind increase the CPU use?


地址:https://stackoverflow.com/questions/2846165/why-does-an-infinite-loop-of-the-unintended-kind-increase-the-cpu-use


5、頻繁 Young GC 會不會引起 CPU 使用率飚升?


會的。


Young GC 本身是 JVM 進行垃圾回收的操作,會計算內(nèi)存和調(diào)用寄存器,頻繁 Young GC 一定是會占用 CPU。


之前有個一個案例,for 循環(huán)從數(shù)據(jù)庫查詢數(shù)據(jù)集合,二次封裝新的數(shù)據(jù)集合,這時如果量比較大時,內(nèi)存沒有足夠的空間存儲,那么 JVM 就會 GC 回收那些不再使用的數(shù)據(jù),因此量大的時候,就會收到 CPU 使用率報警。


6、線程數(shù)很高的應(yīng)用,CPU 使用率一定高么?


不會。


通過 jstack 查看系統(tǒng)線程狀態(tài),查看整個線程數(shù)很多,但 Runable 和 Running 狀態(tài)的線程不多,這時 CPU 使用率不一定會高。


之前有過一個案例,查看系統(tǒng)線程數(shù) 1000+,jstack 分析 900多個線程是 BLOCKED 和 WAITING 狀態(tài)的,這種線程是不會占用 CPU 的。


如果線程數(shù)很高,其實大多數(shù)原因是死鎖,大量線程處于 BLOCKED 和 WAITING 狀態(tài)。


7、CPU 使用率高的應(yīng)用,線程數(shù)一定高么?


不會。


同上,CPU 使用率高的關(guān)鍵因素還是計算密集型操作,一個線程如果有大量計算,也會造成 CPU 使用率高,也是現(xiàn)在為什么一個大數(shù)據(jù)腳本任務(wù),要大規(guī)模集群共同運算才能運行的原因。


8、BLOCKED 狀態(tài)的線程會不會引起 CPU 使用率飚升?


不一定。


CPU使用率的飆升,更多是因為上下文的切換或者runnable狀態(tài)線程過多導(dǎo)致。Blocked狀態(tài),未必會引起CPU上升。


9、分時操作系統(tǒng) CPU us高或者sy高是什么意思?


通過top命令,可以觀察到CPU的us,sy值,示例如下:

關(guān)于CPU使用率飆升,我們需要了解什么?

  • us 用戶空間占用CPU百分比,簡單來說,us高是因為程序?qū)е碌?,通過分析線程堆棧,可以很容易的定位到問題線程。


  • sy 內(nèi)核空間占用CPU百分比,sy高的時候,如果是程序問題導(dǎo)致,基本是因為線程上下文切換造成的。

CPU飆升線程定位示例:

public class cpuTest {
public static void main(String args[]){
for(int i=0;i<10;i++){
new Thread(){
public void run(){
try{
Thread.sleep(100000);
}catch(Exception e){}
}
}.start();
}
Thread t=new Thread(){
public void run(){
int i=0;
while(true){
i=(i++)/100;
}
}
};
t.setName("Busiest Thread");
t.start();
}
}


步驟1: 執(zhí)行top -c ,顯示進程運行信息列表,鍵入P (大寫p),進程按照CPU使用率排序,最耗CPU的進程PID為18207

步驟2:首先我們可以通過top -Hp <pid>來看這個進程里所有線程的cpu消耗情況

$ top -Hp 18207top - 19:11:43 up 573 days,  2:43,  2 users,  load average: 3.03, 3.03, 3.02Tasks:  44 total,   1 running,  43 sleeping,   0 stopped,   0 zombieCpu(s): 18.8%us,  0.0%sy,  0.0%ni, 81.1%id,  0.0%wa,  0.0%hi,  0.0%si,  0.0%stMem:  99191752k total, 98683576k used,   508176k free,   128248k buffersSwap:  1999864k total,   191064k used,  1808800k free, 17413760k cached PID  USER      PR  NI  VIRT  RES  SHR S %CPU %MEM    TIME+  COMMAND18250 admin     20   0 26.1g  28m  10m R 99.9  0.0   0:19.50 java Test18207 admin     20   0 26.1g  28m  10m S  0.0  0.0   0:00.00 java Test18208 admin     20   0 26.1g  28m  10m S  0.0  0.0   0:00.09 java Test18209 admin     20   0 26.1g  28m  10m S  0.0  0.0   0:00.00 java Test18210 admin     20   0 26.1g  28m  10m S  0.0  0.0   0:00.00 java Test18211 admin     20   0 26.1g  28m  10m S  0.0  0.0   0:00.00 java

cpu最高的線程是pid為18250的線程,占了99.9%

步驟3:printf “%x\n” 18250將線程PID轉(zhuǎn)化為16進制

$ printf “%x\n” 18250

0X47A

...

步驟4:jstack 18207|grep'0X47A'-C5 --color找出進程中消耗CPU最多的線程棧

$ jstack 18207|grep'0X47A'-C5 --colorFull thread dump OpenJDK 64-Bit Server VM (25.66-b60 mixed mode):"Attach Listener" #30 daemon prio=9 os_prio=0 tid=0x00007fb90be13000 nid=0x47d7 waiting on condition [0x0000000000000000]   java.lang.Thread.State: RUNNABLE"DestroyJavaVM" #29 prio=5 os_prio=0 tid=0x00007fb96245b800 nid=0x4720 waiting on condition [0x0000000000000000]   java.lang.Thread.State: RUNNABLE"Busiest Thread" #28 prio=5 os_prio=0 tid=0x00007fb91498d000 nid=0x474a runnable [0x00007fb9065fe000]   java.lang.Thread.State: RUNNABLE    at Test$2.run(Test.java:18)"Thread-9" #27 prio=5 os_prio=0 tid=0x00007fb91498c800 nid=0x4749 waiting on condition [0x00007fb906bfe000]   java.lang.Thread.State: TIMED_WAITING (sleeping)    at java.lang.Thread.sleep(Native Method)    at Test$1.run(Test.java:9)...

因此,最耗cpu的線程是Busiest Thread


日常程序中常見的耗CPU的操作:

1、頻繁GC,訪問量高時,有可能造成頻繁的GC、甚至FGC。當(dāng)調(diào)用量大時,內(nèi)存分配過快,就會造成GC線程不停的執(zhí)行,導(dǎo)致CPU飆高

2、序列化與反序列化,后文中舉了一個真實的案例,程序執(zhí)行xml解析的時,調(diào)用量增大的情況下,導(dǎo)致了CPU被打滿

3、加密解密

4、正則表達式校驗,曾經(jīng)線上發(fā)生一次血案,正則校驗將CPU打滿。大概原因是:Java 正則表達式使用的引擎實現(xiàn)是 NFA 自動機,這種引擎在進行字符匹配會發(fā)生回溯(backtracking)

5、線程上下文切換、當(dāng)啟動了很多線程,而這些線程都處于不斷的阻塞狀態(tài)(鎖等待、IO等待等)和執(zhí)行狀態(tài)的變化過程中。當(dāng)鎖競爭激烈時,很容易出現(xiàn)這種情況

6、某些線程在做無阻塞的運算,簡單的例子while(true)中不停的做運算,沒有任何阻塞。寫程序時,如果需要做很久的計算,可以適當(dāng)將程序sleep下

7、Excel 導(dǎo)出事件


頻繁GC案例

案例背景:網(wǎng)關(guān)服務(wù)進行控制單個url訪問次數(shù)限流,CPU過若干天后飆升到80%,重啟服務(wù)過若干天后又再次飆升到80%

分析過程:通過上述方法進行線程棧定位,并進行內(nèi)存堆分析,發(fā)現(xiàn)pathRaterLimiterConcurrentHashMap對象占用大量堆空間,找到程序中對應(yīng)的filter過濾器代碼如下

public HttpRequestMessage apply(HttpRequestMessage request) {
String requestPath = request.getPath();
if (pathRaterLimiterConcurrentHashMap.containsKey(requestPath)) {
if (!pathRaterLimiterConcurrentHashMap.get(requestPath).tryAcquire()) {
log.warn("too many request:"+requestPath+",time:"+System.currentTimeMillis());
SessionContext context = request.getContext();
if(requestPath!=null && requestPath.equals("/voting/selection")){
context.setEndpoint(VoteTimeOutEndpoint.class.getCanonicalName());
}
//context.setEndpoint(ManyRequestsEndpoint.class.getCanonicalName());
request.setPath("/404.html");
context.setRouteVIP("limit-api");
}
} else {
pathRaterLimiterConcurrentHashMap.put(requestPath, RateLimiter.create(limit));
pathRaterLimiterConcurrentHashMap.get(requestPath).tryAcquire();
}
return request;
}

分析發(fā)現(xiàn)當(dāng)url不斷增加時,map的k-v會不斷增加,以至于最后頻繁觸發(fā)fullgc,導(dǎo)致cpu飆升。

解決方案:跑一個定時任務(wù)線程定期清理map中的對象,后采用LRU算法重寫一個maputil,定時清理過期的key值。


正則表達式案例

案例背景:前幾天線上一個項目監(jiān)控信息突然報告異常,上到機器上后查看相關(guān)資源的使用情況,發(fā)現(xiàn) CPU 利用率將近 100%。

分析過程:

通過 Java 自帶的線程 Dump 工具,我們導(dǎo)出了出問題的堆棧信息。我們可以看到所有的堆棧都指向了一個名為 validateUrl 的方法,這樣的報錯信息在堆棧中一共超過 100 處。通過排查代碼,我們知道這個方法的主要功能是校驗 URL 是否合法。

很奇怪,一個正則表達式怎么會導(dǎo)致 CPU 利用率居高不下。為了弄清楚復(fù)現(xiàn)問題,我們將其中的關(guān)鍵代碼摘抄出來,做了個簡單的單元測試。

public static void main(String[] args) {
String badRegex = "^([hH][tT]{2}[pP]://|[hH][tT]{2}[pP][sS]://)" +
"(([A-Za-z0-9-~]+).)+([A-Za-z0-9-~\\\\/])+$";
String bugUrl = "http://www.fapiao.com/dddp-web/pdf/download?" +
"request=6e7JGxxxxx4ILd-kExxxxxxxqJ4-CHLmqVnenXC692m7" +
"4H38sdfdsazxcUmfcOH2fAfY1Vw__%5EDadIfJgiEf";
if (bugUrl.matches(badRegex)) {
System.out.println("match!!");
} else {
System.out.println("no match!!");
}
}

正則表達式分為三部分:

第一部分匹配 http 和 https 協(xié)議,第二部分匹配 www. 字符,第三部分匹配許多字符。我看著這個表達式發(fā)呆了許久,也沒發(fā)現(xiàn)沒有什么大的問題。

其實這里導(dǎo)致 CPU 使用率高的關(guān)鍵原因就是:Java 正則表達式使用的引擎實現(xiàn)是 NFA 自動機,這種正則表達式引擎在進行字符匹配時會發(fā)生回溯(backtracking)。而一旦發(fā)生回溯,那其消耗的時間就會變得很長,有可能是幾分鐘,也有可能是幾個小時,時間長短取決于回溯的次數(shù)和復(fù)雜度。

正則表達式是一個很方便的匹配符號,但要實現(xiàn)這么復(fù)雜,功能如此強大的匹配語法,就必須要有一套算法來實現(xiàn),而實現(xiàn)這套算法的東西就叫做正則表達式引擎。簡單地說,實現(xiàn)正則表達式引擎的有兩種方式:DFA 自動機(Deterministic Final Automata 確定型有窮自動機)和 NFA 自動機(Non deterministic Finite Automaton 不確定型有窮自動機)。

對于這兩種自動機,他們有各自的區(qū)別,這里并不打算深入將它們的原理。簡單地說,DFA 自動機的時間復(fù)雜度是線性的,更加穩(wěn)定,但是功能有限。而 NFA 的時間復(fù)雜度比較不穩(wěn)定,有時候很好,有時候不怎么好,好不好取決于你寫的正則表達式。

解決方案:

其實在正則表達式中有這么三種模式:貪婪模式、懶惰模式、獨占模式。在關(guān)于數(shù)量的匹配中,有 + ? * {min,max} 四種,如果只是單獨使用,那么它們就是貪婪模式。

如果在他們之后加多一個 ? 符號,那么原先的貪婪模式就會變成懶惰模式,即盡可能少地匹配。但是懶惰模式還是會發(fā)生回溯現(xiàn)象的。

如果在他們之后加多一個 + 符號,那么原先的貪婪模式就會變成獨占模式,即盡可能多地匹配,但是不回溯。

String goodRegex = "^([hH][tT]{2}[pP]://|[hH][tT]{2}[pP][sS]://)" +
"(([A-Za-z0-9-~]+).)++([A-Za-z0-9-~\\\\/])+$";


Excel導(dǎo)出案例

案例背景:京東某系統(tǒng)使用了poi-ooxml-3.5-final做excel導(dǎo)出功能。起初使用該版本的poi的HSSF配合多線程生成excel,沒有任何問題,后來改成了XSSF生成后上線,導(dǎo)出3w條數(shù)據(jù)時,cpu使用率達到了100%,內(nèi)存達到了100%

關(guān)于CPU使用率飆升,我們需要了解什么?

關(guān)于CPU使用率飆升,我們需要了解什么?

關(guān)于CPU使用率飆升,我們需要了解什么?

由于cpu使用率打爆,內(nèi)存打爆,整個服務(wù)器處于拒絕服務(wù)狀態(tài),而呈現(xiàn)到前端則是應(yīng)用系統(tǒng)大部分卡死。于是業(yè)務(wù)方不斷反復(fù)點擊導(dǎo)出按鈕,狀況不斷擴大到集群內(nèi)其他機器上,導(dǎo)致集群出現(xiàn)雪崩現(xiàn)象。

分析過程

由于服務(wù)器已經(jīng)被打死,內(nèi)存那么高,根本無法dump線上堆內(nèi)存,甚至連jstack查看線程棧都無法使用。因此嘗試在測試機復(fù)盤

關(guān)于CPU使用率飆升,我們需要了解什么?

可見eden空間的s0和s1已經(jīng)無法交換了,eden空間已經(jīng)完全打滿,old空間也一樣打滿,yong gc和full gc都非常頻繁,cpu自然使用率高了,不過不足以打滿整個cpu!現(xiàn)在目前定位到了fullgc沒有回收垃圾,那么需要找到內(nèi)存打滿和為啥沒回收的原因。要想找到內(nèi)存打滿的原因肯定需要分析heap空間對象。

由于問題出現(xiàn)在導(dǎo)出報表,并且已知升級了版本并且改成了單線程導(dǎo)出就解決了,同時之前使用HSSF的時候并沒有出現(xiàn)問題,也證明了業(yè)務(wù)代碼沒有問題,問題出現(xiàn)在XSSF的版本和多線程上。所以本地可以模擬poi-ooxml-3.5-FINAL的XSSF進行大量數(shù)據(jù)的導(dǎo)出實驗,同時需要進行多線程導(dǎo)出。

在本地mock數(shù)據(jù)可以使用簡單的大量對象構(gòu)成的結(jié)構(gòu)進行導(dǎo)出,線上30個列導(dǎo)出,本地測試5個列,線上是本地的6倍,線上的每一行的數(shù)據(jù)量必然要比本地的數(shù)據(jù)量大很多。同時懷疑是poi-ooxml-3.5-FINAL內(nèi)存泄露或內(nèi)存管理出現(xiàn)的問題,那么其實不需要4g內(nèi)存,在2g的內(nèi)存下壓榨到死看看heap中大量的對象是不是poi相關(guān)的就可以了。然后再升級下版本,繼續(xù)壓榨一下看看會不會壓死即可。

public static void main(String[] args) {
int size = 500000;
List<User> users = new ArrayList<>(size);
User user;
for (int i = 0; i < size; i++) {
user = new User();
user.setId(Integer.toUnsignedLong(i));
user.setAge(i + 10);
user.setName("user" + i);
user.setRemark(System.currentTimeMillis() + "");
user.setSex("男");
users.add(user);
}

new Thread(() -{
String[] columnName = {"用戶id", "姓名", "年齡", "性別", "備注"};
Object[][] data = new Object[size][5];
int index = 0;
for (User u : users) {
data[index][0] = u.getId();
data[index][1] = u.getName();
data[index][2] = u.getAge();
data[index][3] = u.getSex();
data[index][4] = u.getRemark();
index++;
}
XSSFWorkbook xssfWorkbook = generateExcel("test", "test", columnName, data);
}).start();
try {
Thread.currentThread().join();//等待子線程結(jié)束
} catch (InterruptedException e) {
e.printStackTrace();
}
}


模擬現(xiàn)象與線上情況類似,大量cpu占用在XSSFCell.setCellValue中,生成excel generateExcel就占據(jù)了所有的cpu,堆信息全是POI對象

關(guān)于CPU使用率飆升,我們需要了解什么?

關(guān)于CPU使用率飆升,我們需要了解什么?

這里還需要注意的是,需要驗證poi-ooxml-3.5-FINAL在多線程情況下是否會出現(xiàn)這個問題,驗證很簡單,把new Thread去掉,直接在主線程導(dǎo)出。這里直接說明實驗結(jié)果,new Thread去了依然內(nèi)存爆滿!

解決方案

查看poi官網(wǎng)的change log http://poi.apache.org/changes.html ,既然3.5-FINAL的XSSF有問題,向上查找3.5-FINAL之后的XSSF相關(guān)字樣的信息,會發(fā)現(xiàn)在3.6中memory usage optimization in xssf - avoid creating parentless xml beans,xxsf進行中做了內(nèi)存優(yōu)化 - 避免了創(chuàng)建無父類的xml bean對象


所以得出結(jié)論,升級poi-oxxml版本到3.6或者更高版本!


   
           
來源:技術(shù)讓夢想更偉大

免責(zé)聲明:本文內(nèi)容由21ic獲得授權(quán)后發(fā)布,版權(quán)歸原作者所有,本平臺僅提供信息存儲服務(wù)。文章僅代表作者個人觀點,不代表本平臺立場,如有問題,請聯(lián)系我們,謝謝!

21ic電子網(wǎng)

掃描二維碼,關(guān)注更多精彩內(nèi)容

本站聲明: 本文章由作者或相關(guān)機構(gòu)授權(quán)發(fā)布,目的在于傳遞更多信息,并不代表本站贊同其觀點,本站亦不保證或承諾內(nèi)容真實性等。需要轉(zhuǎn)載請聯(lián)系該專欄作者,如若文章內(nèi)容侵犯您的權(quán)益,請及時聯(lián)系本站刪除。
換一批
延伸閱讀

LED驅(qū)動電源的輸入包括高壓工頻交流(即市電)、低壓直流、高壓直流、低壓高頻交流(如電子變壓器的輸出)等。

關(guān)鍵字: 驅(qū)動電源

在工業(yè)自動化蓬勃發(fā)展的當(dāng)下,工業(yè)電機作為核心動力設(shè)備,其驅(qū)動電源的性能直接關(guān)系到整個系統(tǒng)的穩(wěn)定性和可靠性。其中,反電動勢抑制與過流保護是驅(qū)動電源設(shè)計中至關(guān)重要的兩個環(huán)節(jié),集成化方案的設(shè)計成為提升電機驅(qū)動性能的關(guān)鍵。

關(guān)鍵字: 工業(yè)電機 驅(qū)動電源

LED 驅(qū)動電源作為 LED 照明系統(tǒng)的 “心臟”,其穩(wěn)定性直接決定了整個照明設(shè)備的使用壽命。然而,在實際應(yīng)用中,LED 驅(qū)動電源易損壞的問題卻十分常見,不僅增加了維護成本,還影響了用戶體驗。要解決這一問題,需從設(shè)計、生...

關(guān)鍵字: 驅(qū)動電源 照明系統(tǒng) 散熱

根據(jù)LED驅(qū)動電源的公式,電感內(nèi)電流波動大小和電感值成反比,輸出紋波和輸出電容值成反比。所以加大電感值和輸出電容值可以減小紋波。

關(guān)鍵字: LED 設(shè)計 驅(qū)動電源

電動汽車(EV)作為新能源汽車的重要代表,正逐漸成為全球汽車產(chǎn)業(yè)的重要發(fā)展方向。電動汽車的核心技術(shù)之一是電機驅(qū)動控制系統(tǒng),而絕緣柵雙極型晶體管(IGBT)作為電機驅(qū)動系統(tǒng)中的關(guān)鍵元件,其性能直接影響到電動汽車的動力性能和...

關(guān)鍵字: 電動汽車 新能源 驅(qū)動電源

在現(xiàn)代城市建設(shè)中,街道及停車場照明作為基礎(chǔ)設(shè)施的重要組成部分,其質(zhì)量和效率直接關(guān)系到城市的公共安全、居民生活質(zhì)量和能源利用效率。隨著科技的進步,高亮度白光發(fā)光二極管(LED)因其獨特的優(yōu)勢逐漸取代傳統(tǒng)光源,成為大功率區(qū)域...

關(guān)鍵字: 發(fā)光二極管 驅(qū)動電源 LED

LED通用照明設(shè)計工程師會遇到許多挑戰(zhàn),如功率密度、功率因數(shù)校正(PFC)、空間受限和可靠性等。

關(guān)鍵字: LED 驅(qū)動電源 功率因數(shù)校正

在LED照明技術(shù)日益普及的今天,LED驅(qū)動電源的電磁干擾(EMI)問題成為了一個不可忽視的挑戰(zhàn)。電磁干擾不僅會影響LED燈具的正常工作,還可能對周圍電子設(shè)備造成不利影響,甚至引發(fā)系統(tǒng)故障。因此,采取有效的硬件措施來解決L...

關(guān)鍵字: LED照明技術(shù) 電磁干擾 驅(qū)動電源

開關(guān)電源具有效率高的特性,而且開關(guān)電源的變壓器體積比串聯(lián)穩(wěn)壓型電源的要小得多,電源電路比較整潔,整機重量也有所下降,所以,現(xiàn)在的LED驅(qū)動電源

關(guān)鍵字: LED 驅(qū)動電源 開關(guān)電源

LED驅(qū)動電源是把電源供應(yīng)轉(zhuǎn)換為特定的電壓電流以驅(qū)動LED發(fā)光的電壓轉(zhuǎn)換器,通常情況下:LED驅(qū)動電源的輸入包括高壓工頻交流(即市電)、低壓直流、高壓直流、低壓高頻交流(如電子變壓器的輸出)等。

關(guān)鍵字: LED 隧道燈 驅(qū)動電源
關(guān)閉