簡體   English   中英

Java CPU使用率應該是100%......但事實並非如此

[英]Java CPU usage should be 100%… but it's not

我正在我的Core i7筆記本電腦上運行一個Java程序,它有8個核心(4個物理,4個HT)。 該程序使用8個並行線程,因此它應該耗盡所有CPU。 使用'-server'參數運行時,它始終為100%。 如果沒有它,它總體上大約在50%-60%之間(總是在100%的峰值和30%的下降時變化)。 這就是我覺得奇怪的事情:當我在調試中運行程序並等待CPU使用率特別低(30%)然后暫停執行以查看八個線程正在做什么時,它們都沒有處於阻塞狀態。 而且,它們之間幾乎沒有同步。 這就是我想知道的:

  1. 服務器和客戶端VM之間有什么區別會阻止CPU在客戶端達到100%?
  2. 在沒有同步的情況下,什么可以阻止線程完全耗盡核心? (可能與1相關)

編輯:這是一個想法:代碼分配大數組並很快將它們留給GC。 調用'new SomethingBig()'並分配該內存需要時間時線程是否會休眠? 如果VM處理一組線程的分配中有一個進程,我想這可以解釋為什么它們似乎在同步塊之外隨機暫停......

編輯2:我很確定它是由GC引起的。 如果我給VM 1500Mb而不是默認的500Mb,則CPU再次達到100%。 我認為在服務器模式下不會發生減速,因為它默認使用更多內存。

特別是與Java沒有關系,但是你擁有的線程數應該超過你必須充分利用CPU的核心數量,這是因為有很多時候特定線程無法執行,以及更明顯地等待另一個線程持有的條件變量,線程可能因其他原因而被阻塞,因為緩存未命中可能需要線程等待將數據加載到cpus緩存中,它可能必須等待來自某些源的輸入比cpu慢,實際上內存分頁可能會導致你的線程等待。 通過擁有比核心更多的線程,當一個線程因任何原因被阻塞時,另一個線程可以使用被釋放的核心。 一個好的初始值大約是你擁有的核心數量的1.5倍。

如果要監視Java線程正在執行的操作,則不應在調試模式下運行App並暫停它。

相反,您應該在CPU使用率下降的特定時間間隔內使用kill -3 <pid> 收集線程轉儲

與第二次更新相關,應啟用帶有時間戳的GC日志記錄,並將減速/ CPU使用量下降與Young / Full GC集合的時間相關聯。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM