[英]RUNNABLE thread - has it moved?
我正在調查在Java 7上運行的Glassfish 3.1.2.2托管應用程序遇到的CPU使用率過高的問題
CPU使用率將在20分鍾的過程中從“正常”水平開始上升,從5-10%上升到100%,然后保持在90-100之間並且不會下降,重新啟動應用程序將恢復正常狀態。
下面的2個摘錄摘自2個線程轉儲,之間的間隔為10分鍾。
將整個轉儲與visualvm CPU profiler快照進行交叉引用顯示,大約有10個線程在執行此代碼區域,這些線程似乎在下面的方法中花費了全部時間。
除了鎖定對象引用之外,所有10個線程的兩個線程轉儲的整個堆棧(以下是很大的縮寫)是相同的。
我想知道這里發生了什么。 包括為什么鎖定對象引用已更改?
代碼是卡在循環中還是在某處有鎖?
線程轉儲1
"http-thread-pool-8080(3)" - Thread t@112
java.lang.Thread.State: RUNNABLE
at java.lang.Throwable.fillInStackTrace(Native Method)
at java.lang.Throwable.fillInStackTrace(Throwable.java:783)
- locked <2328e584> (a java.lang.InterruptedException)
at java.lang.Throwable.<init>(Throwable.java:250)
at java.lang.Exception.<init>(Exception.java:54)
at java.lang.InterruptedException.<init>(InterruptedException.java:57)
at java.util.concurrent.locks.AbstractQueuedSynchronizer.tryAcquireSharedNanos(AbstractQueuedSynchronizer.java:1325)
at java.util.concurrent.locks.ReentrantReadWriteLock$ReadLock.tryLock(ReentrantReadWriteLock.java:873)
at com.sun.corba.ee.impl.oa.poa.POAImpl.acquireLock(POAImpl.java:390)
at com.sun.corba.ee.impl.oa.poa.POAImpl.readLock(POAImpl.java:422)
at com.sun.corba.ee.impl.oa.poa.POAImpl.enter(POAImpl.java:1743)
at com.sun.corba.ee.impl.protocol.CorbaServerRequestDispatcherImpl.getServantWithPI(CorbaServerRequestDispatcherImpl.java:302)
at com.sun.corba.ee.impl.protocol.CorbaServerRequestDispatcherImpl.dispatch(CorbaServerRequestDispatcherImpl.java:196)
at com.sun.corba.ee.impl.protocol.CorbaMessageMediatorImpl.handleRequestRequest(CorbaMessageMediatorImpl.java:1624)
at com.sun.corba.ee.impl.protocol.SharedCDRClientRequestDispatcherImpl.marshalingComplete(SharedCDRClientRequestDispatcherImpl.java:126)
at com.sun.corba.ee.impl.protocol.CorbaClientDelegateImpl.invoke(CorbaClientDelegateImpl.java:273)
at com.sun.corba.ee.impl.protocol.CorbaClientDelegateImpl.is_a(CorbaClientDelegateImpl.java:395)
at org.omg.CORBA.portable.ObjectImpl._is_a(ObjectImpl.java:130)
...
線程轉儲2
"http-thread-pool-8080(3)" - Thread t@112
java.lang.Thread.State: RUNNABLE
at java.lang.Throwable.fillInStackTrace(Native Method)
at java.lang.Throwable.fillInStackTrace(Throwable.java:783)
- locked <83c9c3a> (a java.lang.InterruptedException)
at java.lang.Throwable.<init>(Throwable.java:250)
at java.lang.Exception.<init>(Exception.java:54)
at java.lang.InterruptedException.<init>(InterruptedException.java:57)
at java.util.concurrent.locks.AbstractQueuedSynchronizer.tryAcquireSharedNanos(AbstractQueuedSynchronizer.java:1325)
at java.util.concurrent.locks.ReentrantReadWriteLock$ReadLock.tryLock(ReentrantReadWriteLock.java:873)
at com.sun.corba.ee.impl.oa.poa.POAImpl.acquireLock(POAImpl.java:390)
at com.sun.corba.ee.impl.oa.poa.POAImpl.readLock(POAImpl.java:422)
at com.sun.corba.ee.impl.oa.poa.POAImpl.enter(POAImpl.java:1743)
at com.sun.corba.ee.impl.protocol.CorbaServerRequestDispatcherImpl.getServantWithPI(CorbaServerRequestDispatcherImpl.java:302)
at com.sun.corba.ee.impl.protocol.CorbaServerRequestDispatcherImpl.dispatch(CorbaServerRequestDispatcherImpl.java:196)
at com.sun.corba.ee.impl.protocol.CorbaMessageMediatorImpl.handleRequestRequest(CorbaMessageMediatorImpl.java:1624)
at com.sun.corba.ee.impl.protocol.SharedCDRClientRequestDispatcherImpl.marshalingComplete(SharedCDRClientRequestDispatcherImpl.java:126)
at com.sun.corba.ee.impl.protocol.CorbaClientDelegateImpl.invoke(CorbaClientDelegateImpl.java:273)
at com.sun.corba.ee.impl.protocol.CorbaClientDelegateImpl.is_a(CorbaClientDelegateImpl.java:395)
at org.omg.CORBA.portable.ObjectImpl._is_a(ObjectImpl.java:130)
...
UPDATE
這可能是導致問題的POAImpl acquisitionLock方法...
private void acquireLock(Lock lock) {
MethodMonitor __$mm$__ = (MethodMonitor)__$mm$__0.content();
if (__$mm$__ != null) {
__$mm$__.enter(1, new Object[]{lock});
}
try {
long timeout = 1L;
boolean locked = false;
boolean interrupted = false;
int count = 0;
int reportingThreshhold = 1;
while(!locked) {
if (count >= reportingThreshhold) {
this.acquireLockWaiting(count, __$mm$__, 1);
if (reportingThreshhold < 1073741823) {
reportingThreshhold *= 2;
}
}
try {
locked = lock.tryLock(1L, TimeUnit.SECONDS);
++count;
} catch (InterruptedException var13) {
interrupted = true;
}
if (interrupted) {
Thread.currentThread().interrupt();
}
}
if (__$mm$__ != null) {
__$mm$__.exit(1);
}
} finally {
if (__$mm$__ != null) {
__$mm$__.exit(1);
}
}
}
至於提供的代碼。 其本質上是這樣的:
public static void main(String[] args) throws InterruptedException {
ReentrantLock lock = new ReentrantLock();
Thread t=new Thread(()->lock.lock()); //lets simulate that Lock is locked
t.start();
t.join();
int times = 0;
Thread.currentThread().interrupt(); //and for whatever reasons - thread was interrupted from outside
boolean locked=false;
while (!locked) {
try {
boolean gotLock=lock.tryLock(1, TimeUnit.SECONDS);
System.out.println("Got lock?: "+gotLock);
} catch (InterruptedException e) {
System.out.println("Thrown times:" + times++);
Thread.currentThread().interrupt(); // iterrupts again - will throw on getLock no matter what now
}
}
}
因此,基本上只有一次中斷-您將陷入無限循環的困境-沒有延遲-這會占用CPU。 我建議圍繞該中斷處理添加診斷日志記錄,以查看發生了什么情況。
一種選擇是類似的事情發生在代碼中:
public void doTheJob(){
try{
.... // fail fast for whatever reason
}catch(Exception e){
doTheJob();
}
}
發生異常-這就是為什么我們看到stacktracke的原因。 您陷入了無限循環。
有趣的是,堆棧跟蹤中有一個InterruptedException
,因此看起來您可能試圖殺死一些未完成的(定時)任務,並可能重新安排它們的時間。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.