Java應(yīng)用程序的CPU使用率飆升原因詳細(xì)分析
一. 問題
- while 的無限循環(huán)是否會導(dǎo)致 CPU 使用率飆升?
- 頻繁的 Young GC 是否會導(dǎo)致 CPU 使用率飆升?
- 有大量線程的應(yīng)用程序的 CPU 使用率高嗎?
- CPU 使用率高的應(yīng)用程序的線程數(shù)是否很大?
- 處于 BLOCKED 狀態(tài)的線程是否會導(dǎo)致 CPU 使用率飆升?
- 分時操作系統(tǒng)中的 CPU 是消耗 us(用戶態(tài)) 還是 sy(內(nèi)核態(tài))?
二. 思考
1. 我們?nèi)绾斡嬎?CPU 使用率?
CPU% = (1 - idleTime / sysTime ) * 100
- idleTime:CPU 的空閑時間
- sysTime:CPU 處于用戶態(tài)和內(nèi)核態(tài)的時間總和
2. 常見的 CPU 密集型操作有哪些?
人們常說,計算密集型程序就是 CPU 密集型的,那么,Java 應(yīng)用程序中有哪些操作是計算密集型的呢?
下面列出常見 CPU 密集型操作
- 頻繁的 GC;如果訪問量很大,可能會導(dǎo)致頻繁的GC甚至Full GC。當(dāng)調(diào)用量大時,內(nèi)存分配會非???,以至于 GC 線程會不斷執(zhí)行,導(dǎo)致 CPU 飆升。
- 序列化和反序列化
- 加密和解碼。
- 正則表達(dá)式。原因可能是Java正則表達(dá)式使用的引擎實(shí)現(xiàn)是NFA自動機(jī),它會在字符匹配時進(jìn)行回溯。
- 線程上下文切換。有很多啟動的線程,這些線程的狀態(tài)在 Blocked(鎖等待、IO等待等)和 Running 之間不斷變化,當(dāng)鎖爭用激烈時,這種情況很容易發(fā)生。
- 一些線程不斷執(zhí)行非阻塞操作,例如while (true)語句。如果程序中計算時間較長,可以休眠線程。
3. CPU 與 進(jìn)程和線程有關(guān)嗎?
現(xiàn)在,分時操作系統(tǒng)采用輪詢的方式為進(jìn)程調(diào)度分配時間片。如果進(jìn)程正在等待或阻塞,則它不會使用 CPU 資源。線程稱為輕進(jìn)程,共享進(jìn)程資源,因此線程調(diào)度在 CPU 中也是分時的。但是在 Java 中,我們使用 JVM 進(jìn)行線程調(diào)度,所以一般來說,線程的調(diào)度有兩種模式:分時調(diào)度和搶占式調(diào)度。線程和進(jìn)程在阻塞或者等待時,都不會使用 CPU 資源。
三. 答案
1. while的無限循環(huán)是否導(dǎo)致CPU使用率飆升?
回答:是的
分析:首先,無限循環(huán)會調(diào)用CPU寄存器進(jìn)行計數(shù),這個操作會占用CPU資源。那么,如果線程一直處于死循環(huán)狀態(tài),CPU會不會切換線程呢?除非操作系統(tǒng)時間片到期,否則無限循環(huán)不會放棄占用的CPU資源,并且無限循環(huán)會繼續(xù)向系統(tǒng)請求時間片,直到系統(tǒng)沒有空閑時間做其他事情。
2. 頻繁的Young GC會導(dǎo)致CPU使用率飆升嗎?
回答:是的
分析:Young GC 本身就是 JVM 進(jìn)行垃圾回收的操作,需要計算內(nèi)存和調(diào)用寄存器,因此頻繁的 Young GC 肯定會占用 CPU 資源。
讓我們來看一個真實(shí)的案例:for 循環(huán)從數(shù)據(jù)庫中查詢數(shù)據(jù)集合,然后再次封裝新的數(shù)據(jù)集合。如果內(nèi)存不夠存儲,JVM 會回收不再使用的數(shù)據(jù)。因此,如果需要的存儲空間很大,可能會收到 CPU 使用率警報。
3. 線程多的應(yīng)用CPU使用率一定高嗎?
回答:不一定
分析:如果我們通過 jstack 查看系統(tǒng)線程狀態(tài)時線程總數(shù)很大,但處于 Runnable 和 Running 狀態(tài)的線程并不多,那么 CPU 使用率不一定高。但是大多數(shù)情況下,如果線程數(shù)很大,那么常見的原因是大量線程處于 BLOCKED 和 WAITING 狀態(tài)
4. CPU 使用率高的應(yīng)用程序的線程數(shù)一定大嗎?
回答:不一定
分析:CPU 使用率高的關(guān)鍵因素是計算密集型操作。如果一個線程有大量計算,CPU使用率也可能很高,這也是一個數(shù)據(jù)腳本任務(wù)需要在大規(guī)模集群上運(yùn)行的原因。
5. 處于BLOCKED狀態(tài)的線程是否會導(dǎo)致CPU使用率飆升?
回答:不一定
分析:CPU 使用率的飆升更多是因?yàn)樯舷挛那袚Q或過多的可運(yùn)行狀態(tài)線程。處于阻塞狀態(tài)的線程不一定會導(dǎo)致 CPU 使用率上升。
6 . CPU的us和sy值在分時操作系統(tǒng)中高是什么意思?
我們可以使用 top 命令查看 CPU 的 us 和 sy 的值,如下圖所示:
us:用戶空間占用 CPU 的百分比。簡單來說,如果 us 的值比較高,則是我們程序引起的,并且分析線程堆棧很容易定位有問題的線程sy:內(nèi)核空間占用 CPU 的百分比。sy 高的時候,如果是程序引起的,那么基本上是線程上下文切換引起的。
四. 經(jīng)驗(yàn)
如何定位CPU使用率高的原因?下面簡要介紹分析過程。
如果發(fā)現(xiàn)某個應(yīng)用服務(wù)器的CPU使用率高,首先檢查線程數(shù)、JVM、系統(tǒng)負(fù)載等參數(shù),然后用這些參數(shù)來證明問題的原因。
其次,用 jstack 打印堆棧信息,使用工具分析線程使用情況(推薦使用在線線程分析工具fastThread)。
到此這篇關(guān)于Java應(yīng)用程序的CPU使用率飆升原因詳細(xì)分析的文章就介紹到這了,更多相關(guān)Java應(yīng)用程序CPU使用率飆升內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
SpringBoot中關(guān)于static和templates的注意事項以及webjars的配置
今天小編就為大家分享一篇關(guān)于SpringBoot中關(guān)于static和templates的注意事項以及webjars的配置,小編覺得內(nèi)容挺不錯的,現(xiàn)在分享給大家,具有很好的參考價值,需要的朋友一起跟隨小編來看看吧2019-01-01java中File與MultipartFile互轉(zhuǎn)代碼示例
在Java開發(fā)中,當(dāng)需要將本地File對象轉(zhuǎn)換為MultipartFile對象以處理文件上傳時,可以通過實(shí)現(xiàn)MultipartFile接口或使用CommonsMultipartFile類來實(shí)現(xiàn),本文提供了詳細(xì)的轉(zhuǎn)換方法和代碼示例,需要的朋友可以參考下2024-10-10Java?map和bean互轉(zhuǎn)常用的方法總結(jié)
這篇文章主要給大家介紹了關(guān)于Java中map和bean互轉(zhuǎn)常用方法的相關(guān)資料,平時日常Java開發(fā),經(jīng)常會涉及到Java?Bean和Map之間的類型轉(zhuǎn)換,需要的朋友可以參考下2023-09-09JavaWeb Servlet生命周期細(xì)枝末節(jié)處深究
Servlet指在服務(wù)器端執(zhí)行的一段Java代碼,可以接收用戶的請求和返回給用戶響應(yīng)結(jié)果,下面這篇文章主要給大家介紹了關(guān)于JavaWeb.servlet生命周期的相關(guān)資料,需要的朋友可以參考下2022-10-10編譯大型Java項目class沖突導(dǎo)致報錯的解決方案
這篇文章給大家盤點(diǎn)編譯大型項目class沖突導(dǎo)致報錯的解決方案,文中通過代碼示例介紹的非常詳細(xì),具有一定的參考價值,需要的朋友可以參考下2023-10-10關(guān)于java.lang.IncompatibleClassChangeError錯誤解決方案
最近開發(fā)中遇到類沖突報錯 java.lang.IncompatibleClassChangeError,所以下面這篇文章主要給大家介紹了關(guān)于java.lang.IncompatibleClassChangeError錯誤的解決方案,需要的朋友可以參考下2024-02-02聊聊@RequestParam,@PathParam,@PathVariable等注解的區(qū)別
這篇文章主要介紹了聊聊@RequestParam,@PathParam,@PathVariable等注解的區(qū)別,具有很好的參考價值,希望對大家有所幫助。一起跟隨小編過來看看吧2021-02-02Springboot實(shí)現(xiàn)從controller中跳轉(zhuǎn)到指定前端頁面
Springboot實(shí)現(xiàn)從controller中跳轉(zhuǎn)到指定前端頁面方式,具有很好的參考價值,希望對大家有所幫助,如有錯誤或未考慮完全的地方,望不吝賜教2023-10-10