我们为在Tomcat 6.0.28和OpenJDK Runtime Environment(IcedTea6 1.11.11)上运行的新版Java EE Web应用程序运行了几次浸泡测试.问题出现在Web层中.
经过一段时间 - 第一次50分钟,第二次1小时,第三次2.5小时 - 我们的集群Web层中的一个随机Tomcat停止响应.看看线程转储,我们看到大量线程突然阻塞.
当问题发生时,线程数从93增加到437.在WebappClassLoader上阻止了437个线程中的341个,如下所示:
"TP-Processor400" daemon prio=10 tid=0x00007f1ee432e800 nid=0x44d9 waiting for monitor entry [0x00007f1ec47c5000]
java.lang.Thread.State: BLOCKED (on object monitor)
at org.apache.catalina.loader.WebappClassLoader.loadClass(WebappClassLoader.java)
- waiting to lock <0x00000006f561a758> (a org.apache.catalina.loader.WebappClassLoader)
at org.apache.catalina.loader.WebappClassLoader.loadClass(WebappClassLoader.java:1329)
Run Code Online (Sandbox Code Playgroud)
一个线程持有锁:
"TP-Processor53" daemon prio=10 tid=0x00007f1ee406f800 nid=0x7cbf runnable [0x00007f1f4545b000]
java.lang.Thread.State: RUNNABLE
at java.lang.ClassLoader.findLoadedClass0(Native Method)
at java.lang.ClassLoader.findLoadedClass(ClassLoader.java:923)
at org.apache.catalina.loader.WebappClassLoader.loadClass(WebappClassLoader.java:1386)
- locked <0x00000006f561a758> (a org.apache.catalina.loader.WebappClassLoader)
at org.apache.catalina.loader.WebappClassLoader.loadClass(WebappClassLoader.java:1329)
Run Code Online (Sandbox Code Playgroud)
一分钟间隔内的后续线程转储显示锁被释放,然后由其他一些线程获取.2分钟后,所有被阻止的线程都被解除阻塞,服务器再次正常运行.
已经在Tomcat错误跟踪器上报告了WebappClassLoader的死锁问题,应用程序使用自己的类加载器(https://issues.apache.org/bugzilla/show_bug.cgi?id=48694,这是https://问题的副本.apache.org/bugzilla/show_bug.cgi?id = 48903),我们也是如此:我们的应用程序嵌入在集群OpenCMS安装中,该安装使用org.opencms.ocee.base.CmsReloadingClassLoader来加载类.
当阻塞发生时,我们也看到GC活动从CPU时间的10%增加到50%,即使内存和堆在那时没有增加.
问题是这个阻塞是由什么引起的,我们可以做些什么来解决它?
关于EJB的问题:
假设我有一个具有无限循环的会话bean.它在EJB事务下运行.现在当EJB的事务超时时,会导致无限循环线程中断或容器将停止运行无限循环的线程.