2015-06-22 48 views
12

我已經看到其他對此問題的引用,例如herehere,儘管這些引用了不同版本的Netty。嘗試使用4.0分支(4.0.29)和5.0 alpha分支(5.0-Alpha3)中的最新版本。本地(非Linux)jdk 1.8.040,沒問題。使用java jdk 1.8.025-b17的遠程(Linux)獲得100%cpu。 Linux內核版本2.6.32。以100%CPU運行的Netty

使用EpollEventLoopGroup();

打過電話

workerGroup = new NioEventLoopGroup(); 
workerGroup.rebuildSelectors(); 

誰能提供任何建議試過嗎?我已經看到了引用這個bug的不同版本的Netty。 JDK的bug? Netty錯誤?流程在啓動時立即達到100%並停留在那裏。

更新:升級到Java 1.8.045,相同的區別。

JStack output所有可運行的線程(裏面有一些rabbitmq的東西,只是爲了完整性而包含 - 這對其他應用程序來說很常見,並且不是問題的原因)。

+1

如果你可以運行'top -H -p '和'jstack ',你可以看到哪些線程使用CPU和這些線程的堆棧。我還建議運行'jstat -gc '以確保它不是內存問題。 –

+0

感謝您的建議。 top -H -p 顯示使用所有cpi的1個子進程。 jstack顯示了不等待的唯一東西是epollWait和java.net.SocketInputStream.socketRead0(Native Method)。 –

+0

你可以發佈'top'和'jstack'的輸出嗎? enire jstack-output,但是對於'top'最高的5個線程就足夠了。 –

回答

10

正如我們在意見中指明,所消耗的CPU線程是忙着在下面的堆棧:

"pool-9-thread-1" #49 prio=5 os_prio=0 tid=0x00007ffd508e8000 nid=0x3a0c runnable [0x00007ffd188b6000] 
    java.lang.Thread.State: RUNNABLE 
    at java.util.concurrent.ScheduledThreadPoolExecutor$DelayedWorkQueue.poll(ScheduledThreadPoolExecutor.java:809) 
    at java.util.concurrent.ThreadPoolExecutor.getTask(ThreadPoolExecutor.java:1066) 
    at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1127) 
    at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:617) 
    at java.lang.Thread.run(Thread.java:745) 

我已成功通過創建ScheduledThreadPoolExecutor重現了類似的行爲,將其配置爲允許核心線程超時,並在很短的延遲時間內安排大量重複任務。它在我的機器上產生大量的CPU,並且jstack輸出類似(有時更深入到poll方法中)。這段代碼也再現:

ScheduledThreadPoolExecutor executor = new ScheduledThreadPoolExecutor(1); 
executor.setKeepAliveTime(1, TimeUnit.MINUTES); 
executor.allowCoreThreadTimeOut(true); 
for (long i = 0; i < 1000; i++) { 
    executor.scheduleAtFixedRate(new Runnable() { 

     @Override 
     public void run() { 
     } 
    }, 0, 1, TimeUnit.NANOSECONDS); 
} 

現在,我們只需要確定哪些代碼設置一個破ScheduledThreadPoolExecutor。我搜索了RabbitMQ和Netty源代碼,但沒有發現任何obvoius。它可能是你在自己的代碼中做的事情嗎?

編輯:作爲評價提到的,根本原因是與0初始化的ScheduledThreadPoolExecutor這顯然會導致CPU自旋OM一些平臺。這是在OP的代碼中完成的。

+3

不幸的是,雖然我想說別人有錯,但事實上,這與我自己的代碼有關。事實證明,如果你錯誤地用0初始化一個scheduledThreadPool,你會得到100%的CPU空轉。爲什麼有人會那樣做?上帝只知道 - 當然不是我曾經做過的事情。 在任何情況下,javadoc指定使用<0會拋出一個IllegalArgument,但不會提及0.他們可能應該拋出異常0. 感謝您的幫助,並享受+100。我要去漢堡王申請工作。 –

+0

@SteveB。很高興我能幫上忙。有趣的事業! –

+1

有人可能會這樣做的原因是因爲他們希望每30分鐘安排一次,但整個時間內沒有爲此目的分配線程(僅等待30分鐘) - 因此您允許核心線程超時或甚至將核心線程設置爲0 ...讓它感到慚愧。 – john16384