【发布时间】:2011-03-09 10:04:52
【问题描述】:
我正在对部署在 JBoss 中的 Web 应用程序进行一些负载测试。它启动良好,但随着测试的增加和更多模拟用户开始使用 JBoss,性能严重下降:
将VisualVM连接到它,我可以看到线程都很好,然后突然开始花费大部分时间等待监视器(绿色正在运行,红色是监视器,黄色是等待):
运行jstack,我看到线程都在同一个地方等待:
"http-0.0.0.0-8080-172" 守护进程prio=6 tid=0x000000005da90000 nid=0xd2c 等待监视器条目[0x000000006cb4e000]
java.lang.Thread.State: BLOCKED (在对象监视器上)
在 org.apache.log4j.Category.callAppenders(Category.java:185)
- 等待锁定(org.apache.log4j.spi.RootCategory)
在 org.apache.log4j.Category.forcedLog(Category.java:372)
在 org.apache.log4j.Category.debug(Category.java:241)
[我的代码]
大约 200 个 HTTP 处理器线程中的大多数都在等待同一个监视器。查看 WAR 的 log4j.xml,它有一个用于 CONSOLE 的附加程序设置。我删除了 appender 并再次尝试我的测试。相同的行为,除了 jstack 显示所有线程在不同的地方等待:
“http-0.0.0.0-8080-251”守护进程prio=6 tid=0x0000000059811800 nid=0x1108 等待监视器条目[0x0000000073ebe000]
java.lang.Thread.State: BLOCKED (在对象监视器上)
在 java.util.Hashtable.get(Hashtable.java:333)
- 等待锁定(org.jboss.util.property.PropertyMap)
在 java.util.Properties.getProperty(Properties.java:932)
在 org.jboss.util.property.PropertyMap.getProperty(PropertyMap.java:626)
在 java.lang.System.getProperty(System.java:653)
在 org.jaxen.saxpath.helpers.XPathReaderFactory.createReader(XPathReaderFactory.java:109)
在 org.jaxen.BaseXPath.(BaseXPath.java:124)
在 org.jaxen.BaseXPath.(BaseXPath.java:153)
在 nu.xom.JaxenConnector.(JaxenConnector.java:49)
在 nu.xom.Node.query(Node.java:424)
[我的代码]
什么都没有改变,我重新启动 JBoss,运行测试,然后运行 jstack,一旦它变慢了。所有线程都在另一个地方等待:
“http-0.0.0.0-8080-171”守护进程prio=6 tid=0x000000005d0d1000 nid=0x15d4 等待监视器条目[0x000000006cb4e000]
java.lang.Thread.State: BLOCKED (在对象监视器上)
在 sun.nio.cs.FastCharsetProvider.charsetForName(FastCharsetProvider.java:118)
- 等待锁定(sun.nio.cs.StandardCharsets)
在 java.nio.charset.Charset.lookup2(Charset.java:449)
在 java.nio.charset.Charset.lookup(Charset.java:437)
在 java.nio.charset.Charset.isSupported(Charset.java:479)
在 sun.nio.cs.StreamDecoder.forInputStreamReader(StreamDecoder.java:49)
在 java.io.InputStreamReader.(InputStreamReader.java:57)
在 java.io.FileReader.(FileReader.java:41)
[我的代码]
到底发生了什么?我过去使用过 jstack,当一切运行良好并获得预期结果时,我尝试运行它。我认为 jstack 很好。有什么想法会导致这种奇怪的行为吗?关于从这里去哪里的任何想法?
【问题讨论】:
-
没有更多上下文/信息,很难具体说明发生了什么。一般来说,看起来有很多对各种资源的争用和/或可能的死锁情况。作为您的第一步,听起来您删除了一些对 log4j 的争用。是否可以通过缓存查询结果或同步访问可能导致死锁的数据结构的某种组合对其他两种资源做同样的事情?
-
我很乐意提供更多信息,但我不知道该提供什么。奇怪的是,虽然有很多争用,但线程并没有死锁。他们在监视器上等待 2 到 10+ 秒,然后继续执行,然后不久再次在监视器上等待。这些调用非常基本(例如 System.getProperties),无法避免。 JBoss 和其他第三方代码进行这些调用。因为我很确定 System.getProperties 和 HashTable 是可靠的,所以我的下一个最佳猜测是当争用发生时 jstack 具有误导性。如果是这样,我还能如何确定争用发生的位置?
标签: java performance debugging concurrency jboss