性能问答>几百线程等待一把无人持有的锁>
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问题的排查——一把无人持有的锁。但我看不懂他的解决方法....

求各们大佬帮忙分析分析问题出在哪里

701 阅读
请先登录,再评论

发一下 jstack 的信息呢

12月前
回复 1569486:

手机上操作了, 不小心点到采纳了😳

2月前回复
回复 黄金键盘:

关联了stack的
线程栈

2月前回复

真累

1月前

mark

2月前

咸鱼出现同样的问题的原因是业务回环导致consue的处理能力下降,导致创建更多的线程,线程过多出现swap,swap导致唤醒线程的时间增大从而出现无人拥有的锁。老哥可以看下看下jvm的线程是否有swap,如果有的话那就基本上和咸鱼的问题是同样的问题了。那就好解决了

12月前
回复 张策:

你好druid是哪个版本的?

1月前回复
回复 张策:

我看了一下, 服务器swap是关了的。 出问题的时候, 内存free 还有2G左右, cache有11G。

1月前回复
回复 张策:

多谢, 我下午看看

2月前回复

哈哈

2月前
回复 愿得一人心:

大哥帮分析分析

2月前回复

看了线程栈确实没有找到谁持有这把锁、

12月前
回复 1569486:

如果有解决,帮忙评论区告知下,一个充满好奇的开发者😃

2月前回复
回复 小明明:

多谢关注

2月前回复

应用是在tomcat中运行的, tomcat版为8.5。 运行时的jvm选项为:

 -server -Xms12g -Xmx12g -XX:PermSize=256m -XX:MaxPermSize=256m -Djava.library.path=/usr/local/apr/lib
12月前