2014-09-18 78 views
2

我有一個在Glassfish 4(4.1版本13),JDK 1.7 update 67和AWS Linux AMI上運行的澤西島應用程序,我注意到在運行它幾個小時後,CPU使用率上升,即使客戶停下來也會保持住。Glassfish 4灰熊線程沉重的CPU使用率

運行「top -H」標識具有較高CPU使用率的2個http-listener-1內核線程(總數爲16)。然後,我花了線程轉儲來檢查這兩個線程:

"http-listener-1-kernel(3) SelectorRunner" daemon prio=10 tid=0x00007fbc68251000 nid=0xaee runnable [0x00007fbcb55ce000] 
    java.lang.Thread.State: RUNNABLE 
     at sun.nio.ch.EPollArrayWrapper.epollWait(Native Method) 
     at sun.nio.ch.EPollArrayWrapper.poll(EPollArrayWrapper.java:269) 
     at sun.nio.ch.EPollSelectorImpl.doSelect(EPollSelectorImpl.java:79) 
     at sun.nio.ch.SelectorImpl.lockAndDoSelect(SelectorImpl.java:87) 
     - locked <0x000000060263ad88> (a sun.nio.ch.Util$2) 
     - locked <0x000000060263ad78> (a java.util.Collections$UnmodifiableSet) 
     - locked <0x00000006025fb068> (a sun.nio.ch.EPollSelectorImpl) 
     at sun.nio.ch.SelectorImpl.selectNow(SelectorImpl.java:106) 
     at org.glassfish.grizzly.nio.DefaultSelectorHandler.select(DefaultSelectorHandler.java:114) 
     at org.glassfish.grizzly.nio.SelectorRunner.doSelect(SelectorRunner.java:338) 
     at org.glassfish.grizzly.nio.SelectorRunner.run(SelectorRunner.java:278) 
     at org.glassfish.grizzly.threadpool.AbstractThreadPool$Worker.doWork(AbstractThreadPool.java:565) 
     at org.glassfish.grizzly.threadpool.AbstractThreadPool$Worker.run(AbstractThreadPool.java:545) 
     at java.lang.Thread.run(Thread.java:745) 


"http-listener-1-kernel(8) SelectorRunner" daemon prio=10 tid=0x00007fbc6825b800 nid=0xaf3 runnable [0x00007fbcb50c9000] 
    java.lang.Thread.State: RUNNABLE 
     at sun.nio.ch.EPollArrayWrapper.epollWait(Native Method) 
     at sun.nio.ch.EPollArrayWrapper.poll(EPollArrayWrapper.java:269) 
     at sun.nio.ch.EPollSelectorImpl.doSelect(EPollSelectorImpl.java:79) 
     at sun.nio.ch.SelectorImpl.lockAndDoSelect(SelectorImpl.java:87) 
     - locked <0x00000006026648b8> (a sun.nio.ch.Util$2) 
     - locked <0x00000006026648a8> (a java.util.Collections$UnmodifiableSet) 
     - locked <0x0000000602664790> (a sun.nio.ch.EPollSelectorImpl) 
     at sun.nio.ch.SelectorImpl.selectNow(SelectorImpl.java:106) 
     at org.glassfish.grizzly.nio.DefaultSelectorHandler.select(DefaultSelectorHandler.java:114) 
     at org.glassfish.grizzly.nio.SelectorRunner.doSelect(SelectorRunner.java:338) 
     at org.glassfish.grizzly.nio.SelectorRunner.run(SelectorRunner.java:278) 
     at org.glassfish.grizzly.threadpool.AbstractThreadPool$Worker.doWork(AbstractThreadPool.java:565) 
     at org.glassfish.grizzly.threadpool.AbstractThreadPool$Worker.run(AbstractThreadPool.java:545) 
     at java.lang.Thread.run(Thread.java:745) 

有趣的是,不消耗CPU的其他線程使用的sun.nio.ch.SelectorImpl不同的方法(選擇而非selectNow):

"http-listener-1-kernel(7) SelectorRunner" daemon prio=10 tid=0x00007fbc68259800 nid=0xaf2 runnable [0x00007fbcb51ca000] 
    java.lang.Thread.State: RUNNABLE 
     at sun.nio.ch.EPollArrayWrapper.epollWait(Native Method) 
     at sun.nio.ch.EPollArrayWrapper.poll(EPollArrayWrapper.java:269) 
     at sun.nio.ch.EPollSelectorImpl.doSelect(EPollSelectorImpl.java:79) 
     at sun.nio.ch.SelectorImpl.lockAndDoSelect(SelectorImpl.java:87) 
     - locked <0x0000000602665f20> (a sun.nio.ch.Util$2) 
     - locked <0x0000000602665f10> (a java.util.Collections$UnmodifiableSet) 
     - locked <0x0000000602665df8> (a sun.nio.ch.EPollSelectorImpl) 
     at sun.nio.ch.SelectorImpl.select(SelectorImpl.java:98) 
     at org.glassfish.grizzly.nio.DefaultSelectorHandler.select(DefaultSelectorHandler.java:112) 
     at org.glassfish.grizzly.nio.SelectorRunner.doSelect(SelectorRunner.java:338) 
     at org.glassfish.grizzly.nio.SelectorRunner.run(SelectorRunner.java:278) 
     at org.glassfish.grizzly.threadpool.AbstractThreadPool$Worker.doWork(AbstractThreadPool.java:565) 
     at org.glassfish.grizzly.threadpool.AbstractThreadPool$Worker.run(AbstractThreadPool.java:545) 
     at java.lang.Thread.run(Thread.java:745) 

然後我再次打開客戶端,讓他們再運行幾個小時,然後再次停止。果然,「top -H」表明CPU使用率再次增加。另一個線程轉儲揭示了一個更加線程切換到「selectNow」,現在(與其他2一起)採取更多的CPU時間:

"http-listener-1-kernel(6) SelectorRunner" daemon prio=10 tid=0x00007fbc68257800 nid=0xaf1 runnable [0x00007fbcb52cb000] 
    java.lang.Thread.State: RUNNABLE 
     at sun.nio.ch.EPollArrayWrapper.epollWait(Native Method) 
     at sun.nio.ch.EPollArrayWrapper.poll(EPollArrayWrapper.java:269) 
     at sun.nio.ch.EPollSelectorImpl.doSelect(EPollSelectorImpl.java:79) 
     at sun.nio.ch.SelectorImpl.lockAndDoSelect(SelectorImpl.java:87) 
     - locked <0x00000006026675c0> (a sun.nio.ch.Util$2) 
     - locked <0x00000006026675b0> (a java.util.Collections$UnmodifiableSet) 
     - locked <0x0000000602667498> (a sun.nio.ch.EPollSelectorImpl) 
     at sun.nio.ch.SelectorImpl.selectNow(SelectorImpl.java:106) 
     at org.glassfish.grizzly.nio.DefaultSelectorHandler.select(DefaultSelectorHandler.java:114) 
     at org.glassfish.grizzly.nio.SelectorRunner.doSelect(SelectorRunner.java:338) 
     at org.glassfish.grizzly.nio.SelectorRunner.run(SelectorRunner.java:278) 
     at org.glassfish.grizzly.threadpool.AbstractThreadPool$Worker.doWork(AbstractThreadPool.java:565) 
     at org.glassfish.grizzly.threadpool.AbstractThreadPool$Worker.run(AbstractThreadPool.java:545) 
     at java.lang.Thread.run(Thread.java:745) 

看來,東西導致線程調用的「selectNow」方法sun.nio.ch.SelectorImpl,一旦它們進入那裏,CPU使用率將大量增加,並且不會減少,除非服務器重新啓動。

這是一個已知的問題?這可能是由我的代碼造成的?

感謝您的幫助!

+0

「http-thread-pool」中有多少個線程?如果沒有足夠的線程來處理請求,那麼SelectRunner可能會「旋轉」。 – dlaudams 2017-06-16 01:54:20

回答