Java 可运行线程-它移动了吗?
我正在调查运行在Java 7上的Glassfish 3.1.2.2托管应用程序遇到的CPU使用率高的问题 CPU使用率将开始从“正常”水平上升,在20分钟内从5-10%上升到100%,然后保持在90-100%之间,而不是下降,重新启动应用程序将恢复正常 下面的2段摘录摘自2个线程转储,它们之间间隔10分钟 通过visualvm CPU profiler快照交叉引用整个转储,可以看到大约有10个线程在执行这一区域的代码,这些线程似乎在下面的方法中花费了全部时间 除了锁定对象引用之外,所有10个线程的两个线程转储中的整个堆栈(巨大&缩写如下)都是相同的 我想知道这里发生了什么事。包括为什么锁定的对象引用已更改 代码是卡在循环中还是某个地方有锁 线程转储1Java 可运行线程-它移动了吗?,java,glassfish-3,jstack,Java,Glassfish 3,Jstack,我正在调查运行在Java 7上的Glassfish 3.1.2.2托管应用程序遇到的CPU使用率高的问题 CPU使用率将开始从“正常”水平上升,在20分钟内从5-10%上升到100%,然后保持在90-100%之间,而不是下降,重新启动应用程序将恢复正常 下面的2段摘录摘自2个线程转储,它们之间间隔10分钟 通过visualvm CPU profiler快照交叉引用整个转储,可以看到大约有10个线程在执行这一区域的代码,这些线程似乎在下面的方法中花费了全部时间 除了锁定对象引用之外,所有10个线程
"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)
...
“http-thread-pool-8080(3)”-线程t@112
java.lang.Thread.State:可运行
位于java.lang.Throwable.fillInStackTrace(本机方法)
位于java.lang.Throwable.fillInStackTrace(Throwable.java:783)
-锁定(java.lang.InterruptedException)
位于java.lang.Throwable。(Throwable.java:250)
位于java.lang.Exception。(Exception.java:54)
位于java.lang.InterruptedException。(InterruptedException.java:57)
位于java.util.concurrent.locks.AbstractQueuedSynchronizer.tryAcquireSharedNanos(AbstractQueuedSynchronizer.java:1325)
位于java.util.concurrent.locks.ReentrantReadWriteLock$ReadLock.tryLock(ReentrantReadWriteLock.java:873)
com.sun.corba.ee.impl.oa.poa.POAImpl.acquireLock(POAImpl.java:390)
com.sun.corba.ee.impl.oa.poa.POAImpl.readLock(POAImpl.java:422)
在com.sun.corba.ee.impl.oa.poa.POAImpl.enter上(POAImpl.java:1743)
位于com.sun.corba.ee.impl.protocol.CorbaServerRequestDispatcherImpl.getServantWithPI(CorbaServerRequestDispatcherImpl.java:302)
位于com.sun.corba.ee.impl.protocol.CorbaServerRequestDispatcherImpl.dispatch(CorbaServerRequestDispatcherImpl.java:196)
位于com.sun.corba.ee.impl.protocol.CorbaMessageMediatorImpl.HandlerRequest(CorbaMessageMediatorImpl.java:1624)
在com.sun.corba.ee.impl.protocol.SharedCDRClientRequestDispatcherImpl.marshalingComplete上(SharedCDRClientRequestDispatcherImpl.java:126)
位于com.sun.corba.ee.impl.protocol.CorbaClientDelegateImpl.invoke(CorbaClientDelegateImpl.java:273)
com.sun.corba.ee.impl.protocol.CorbaClientDelegateImpl.is_a(CorbaClientDelegateImpl.java:395)
在org.omg.CORBA.portable.ObjectImpl._是_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)
...
“http-thread-pool-8080(3)”-线程t@112
java.lang.Thread.State:可运行
位于java.lang.Throwable.fillInStackTrace(本机方法)
位于java.lang.Throwable.fillInStackTrace(Throwable.java:783)
-锁定(java.lang.InterruptedException)
位于java.lang.Throwable。(Throwable.java:250)
位于java.lang.Exception。(Exception.java:54)
位于java.lang.InterruptedException。(InterruptedException.java:57)
位于java.util.concurrent.locks.AbstractQueuedSynchronizer.tryAcquireSharedNanos(AbstractQueuedSynchronizer.java:1325)
位于java.util.concurrent.locks.ReentrantReadWriteLock$ReadLock.tryLock(ReentrantReadWriteLock.java:873)
com.sun.corba.ee.impl.oa.poa.POAImpl.acquireLock(POAImpl.java:390)
com.sun.corba.ee.impl.oa.poa.POAImpl.readLock(POAImpl.java:422)
在com.sun.corba.ee.impl.oa.poa.POAImpl.enter上(POAImpl.java:1743)
位于com.sun.corba.ee.impl.protocol.CorbaServerRequestDispatcherImpl.getServantWithPI(CorbaServerRequestDispatcherImpl.java:302)
位于com.sun.corba.ee.impl.protocol.CorbaServerRequestDispatcherImpl.dispatch(CorbaServerRequestDispatcherImpl.java:196)
位于com.sun.corba.ee.impl.protocol.CorbaMessageMediatorImpl.HandlerRequest(CorbaMessageMediatorImpl.java:1624)
在com.sun.corba.ee.impl.protocol.SharedCDRClientRequestDispatcherImpl.marshalingComplete上(SharedCDRClientRequestDispatcherImpl.java:126)
位于com.sun.corba.ee.impl.protocol.CorbaClientDelegateImpl.invoke(CorbaClientDelegateImpl.java:273)
com.sun.corba.ee.impl.protocol.CorbaClientDelegateImpl.is_a(CorbaClientDelegateImpl.java:395)
在org.omg.CORBA.portable.ObjectImpl._是_a(ObjectImpl.java:130)
...
更新
这是可能导致问题的POAImpl acquireLock方法
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);
}
}
}
private void acquiredlock(锁锁){
MethodMonitor _$mm$_=(MethodMonitor)_$mm$_u0.content();
如果(_$mm$_!=null){
__$mm$\输入(1,新对象[]{lock});
}
试一试{
长超时=1L;
布尔锁定=假;
布尔值=假;
整数计数=0;
int reportingthreshold=1;
当(!锁定){
如果(计数>=reportingThreshhold){
这个.acquireLockWaiting(count,_u$mm$uu;,1);
如果(报告threshhold<1073741823){
报告threshold*=2;
}
}
试一试{
锁定=锁定时间锁定(1L,时间单位为秒);
++计数;
}捕获(中断异常var13){
中断=真;
}
如果(中断){
Thread.currentThread().interrupt();
}
}
如果(_$mm$_!=null){
__$mm$\退出(1);
}
}最后{
如果(_$mm$_!=null){
__$mm$\退出(1);
}
}
}
一种选择是,类似的情况在代码中发生:
public void doTheJob(){
try{
.... // fail fast for whatever reason
}catch(Exception e){
doTheJob();
}
}
出现异常-这就是我们看到stacktracke的原因。你有一个无限循环
非常有趣的是,stacktrace中有一个InterruptedException
,因此看起来您可能会试图杀死一些挂起的异常
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
}
}
}