首先CPU是整個(gè)電腦的核心計(jì)算資源卦绣,對(duì)于一個(gè)應(yīng)用程序來說CPU的最小執(zhí)行單元是線程常柄,導(dǎo)致CPU飆高的原因有兩個(gè)方面棋嘲。
第一個(gè)是CPU的上下文切換過多對(duì)CPU來說同一個(gè)時(shí)刻下每個(gè)CPU核心只能運(yùn)行一個(gè)線程荠锭,如果有多個(gè)線程要去被執(zhí)行怎么辦堤魁,CPU只能通過上下文切換的方式來執(zhí)行調(diào)度不同的線程蜜暑,上下文切換需要做兩個(gè)事情铐姚。第一個(gè)是保存運(yùn)行中線程的執(zhí)行狀態(tài),第二個(gè)讓處于等待中的線程恢復(fù)執(zhí)行肛捍。這兩個(gè)過程需要CPU執(zhí)行內(nèi)核相關(guān)指令隐绵,去實(shí)現(xiàn)狀態(tài)的保存和恢復(fù),如果較多的上下文切換會(huì)占據(jù)大量的CPU資源從而使得CPU無法去執(zhí)行用戶進(jìn)程中的真正指令導(dǎo)致響應(yīng)速度下降拙毫。在java中文件IO依许、網(wǎng)絡(luò)IO、鎖等待缀蹄,這些都會(huì)去造成線程阻塞峭跳,而線程阻塞就會(huì)去導(dǎo)致CPU的上下文切換膘婶。
第二個(gè)是GPU資源過度消耗,也就是在程序中創(chuàng)建了大量的線程或者有線程一直占據(jù)GPU資源無法被釋放蛀醉,比如說像死循環(huán)悬襟。CPU利用率過高之后導(dǎo)致應(yīng)用程序中的線程無法去獲得CPU的調(diào)度從而影響程序的執(zhí)行效率,所以既然是這兩個(gè)問題導(dǎo)致CPU利用率較高拯刁,于是我們可以通過‘top’命令脊岳,找到CPU利用率較高的進(jìn)程,再通過’Shift+H‘找到進(jìn)程中CPU消耗過高的線程筛璧。這里有兩種情況逸绎,第一種情況:CPU利用率過高的線程一直是同一個(gè)也就是線程ID沒有變化,說明在程序中存在長(zhǎng)期占用CPU沒有釋放的一個(gè)情況夭谤,那么這種情況直接可以通過jstack獲得線程的Dump日志定位到線程目志后就可以找到問題的代碼棺牧。第二種情況:CPU利用率過高的線程ID不斷變化,那么說明線程創(chuàng)建過多需要去挑選幾個(gè)線程ID朗儒,通過jstack去線程dump中去進(jìn)行排查颊乘,最后有可能定位的結(jié)果是程序正常,只是在CPU飆高的那一刻醉锄,用戶訪問量非常大導(dǎo)致系統(tǒng)資源不夠乏悄,那么這個(gè)時(shí)候我們需要采取的手段是去增加系統(tǒng)資源。