简体   繁体   English

RUNNABLE线程-它移动了吗?

[英]RUNNABLE thread - has it moved?

I'm investigating a high CPU usage issue we're experiencing with a Glassfish 3.1.2.2 hosted application running on Java 7 我正在调查在Java 7上运行的Glassfish 3.1.2.2托管应用程序遇到的CPU使用率过高的问题

CPU usage will start to rise from 'normal' levels, around 5-10% to 100% over the course of 20 minutes then stay between 90-100 and not drop, a restart of the app restores normality. CPU使用率将在20分钟的过程中从“正常”水平开始上升,从5-10%上升到100%,然后保持在90-100之间并且不会下降,重新启动应用程序将恢复正常状态。

The 2 excerpts below were taken from 2 thread dumps with 10 minutes between them. 下面的2个摘录摘自2个线程转储,之间的间隔为10分钟。

Cross referencing the entire dump with visualvm CPU profiler snapshots shows there are around 10 threads executing this area of code which seem to have spent the entire time in the method seen below. 将整个转储与visualvm CPU profiler快照进行交叉引用显示,大约有10个线程在执行此代码区域,这些线程似乎在下面的方法中花费了全部时间。

The entire stack (which is huge & abbreviated below) is the same from both thread dumps for all 10 threads apart from the locked object reference. 除了锁定对象引用之外,所有10个线程的两个线程转储的整个堆栈(以下是很大的缩写)是相同的。

I'd like to know what is going on here. 我想知道这里发生了什么。 Including why has the locked object reference changed? 包括为什么锁定对象引用已更改?

Is the code stuck in a loop or is there a lock somewhere? 代码是卡在循环中还是在某处有锁?

thread dump 1 线程转储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)
...

thread dump 2 线程转储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 UPDATE

This is the POAImpl acquireLock method that may be causing the issue... 这可能是导致问题的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);
            }

        }
    }

As for provided code. 至于提供的代码。 Its essentially doing something like this: 其本质上是这样的:

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
        }
    }
}

So basicly having interuption once - you will dive into limbo of infinite loop - without delays - which hogs the CPU. 因此,基本上只有一次中断-您将陷入无限循环的困境-没有延迟-这会占用CPU。 I would suggest adding diagnostic logging around that interuption handling to see what is happening. 我建议围绕该中断处理添加诊断日志记录,以查看发生了什么情况。

One option is that something like that happens in code: 一种选择是类似的事情发生在代码中:

public void doTheJob(){

     try{
       .... // fail fast for whatever reason
     }catch(Exception e){
        doTheJob();
     }
}

Exception occures - thats why we are seeing stacktracke. 发生异常-这就是为什么我们看到stacktracke的原因。 You got yourself an infinite loop. 您陷入了无限循环。

What is very interesting is that there is an InterruptedException in the stacktrace, so it looks alike that you might try to kill some pending (timing out) tasks - and maybe reschedule them. 有趣的是,堆栈跟踪中有一个InterruptedException ,因此看起来您可能试图杀死一些未完成的(定时)任务,并可能重新安排它们的时间。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM