15回复
2年前
几百线程等待一把无人持有的锁
环境参数
- 操作系统Linux
- 操作系统版本CentOS Linux release 7.9.2009
- JDK版本JDK7
- 内存32GB
- CPU核数8
- 操作系统位数64位
20220317175714.stack3.78MB
最近有两台服务器经常出现此问题。 操作系统分别为centos7.9 和 centos6.10, jdk1.7.0_80。
现象为: cpu负载降低但还是有一定负载, 带宽使用明显下降, jvm并没有卡死,还是有部分业务能执行, 堆内存使用速度明显变慢, gc频率降低。
通过关联的线程栈分析,可以看到有370个线程在等待 `java.util.IdentityHashMap` 这把锁。 但是没有线程持有些锁。
同步块代码是Druid连接池的com.alibaba.druid.pool.DruidDataSource.getConnectionDirect方法, 同步块处代码为:
if (isRemoveAbandoned()) {
StackTraceElement[] stackTrace = Thread.currentThread().getStackTrace();
poolableConnection.setConnectStackTrace(stackTrace);
poolableConnection.setConnectedTimeNano();
poolableConnection.setTraceEnable(true);
synchronized (activeConnections) {
activeConnections.put(poolableConnection, PRESENT);
}
}
需要说明的是:这几次发生此现象的时候锁的地方不固定。 有时候是hibernate的getCache, 有时候是SSL相关的,还有其它的。
我的认知当中,正常情况下,至少会有一个线程持人锁, 才会导致其它线程等待, 这种无人持有的情况完全超出了理解范围。
网上有和这种情况相似的一篇文章:一次线上JVM问题的排查——一把无人持有的锁。但我看不懂他的解决方法....
求各们大佬帮忙分析分析问题出在哪里
1630 阅读