gpt4 book ai didi

java - RUNNABLE 线程 - 它移动了吗?

转载 作者:行者123 更新时间:2023-12-02 09:39:38 25 4
gpt4 key购买 nike

我正在调查在 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)
...

更新

这是可能导致问题的 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);
}

}
}

最佳答案

至于提供的代码。它本质上是做这样的事情:

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。我建议围绕该中断处理添加诊断日志记录,以查看发生了什么。

关于java - RUNNABLE 线程 - 它移动了吗?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/57203090/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com