我们的基准测试发现了 Apache Tomcat 7.0.59 中的引导瓶颈。当服务器达到其性能极限时,其大部分线程被 ClassLoader 锁定。
阻塞线程的堆栈跟踪如下例所示:
"http-bio-4504-exec-500" Id=2335 BLOCKED on java.util.jar.JarFile@464f9f8 owned by "[1432628598653] POST /services/signin HTTP/1.0" Id=1990
at java.util.zip.ZipFile.getEntry(ZipFile.java:304)
- blocked on java.util.jar.JarFile@464f9f8
at java.util.jar.JarFile.getEntry(JarFile.java:226)
at java.util.jar.JarFile.getJarEntry(JarFile.java:209)
at sun.misc.URLClassPath$JarLoader.getResource(URLClassPath.java:840)
at sun.misc.URLClassPath$JarLoader.findResource(URLClassPath.java:818)
at sun.misc.URLClassPath$1.next(URLClassPath.java:226)
at sun.misc.URLClassPath$1.hasMoreElements(URLClassPath.java:236)
at java.net.URLClassLoader$3$1.run(URLClassLoader.java:583)
at java.net.URLClassLoader$3$1.run(URLClassLoader.java:581)
at java.security.AccessController.doPrivileged(Native Method)
at java.net.URLClassLoader$3.next(URLClassLoader.java:580)
at java.net.URLClassLoader$3.hasMoreElements(URLClassLoader.java:605)
at sun.misc.CompoundEnumeration.next(CompoundEnumeration.java:45)
at sun.misc.CompoundEnumeration.hasMoreElements(CompoundEnumeration.java:54)
at sun.misc.CompoundEnumeration.next(CompoundEnumeration.java:45)
at sun.misc.CompoundEnumeration.hasMoreElements(CompoundEnumeration.java:54)
at com.sun.xml.ws.util.ServiceFinder$LazyIterator.hasNext(ServiceFinder.java:443)
at com.sun.xml.ws.util.ServiceFinder$CompositeIterator.hasNext(ServiceFinder.java:390)
at com.sun.xml.ws.api.message.saaj.SAAJFactory.getMessageFactory(SAAJFactory.java:96)
at com.sun.xml.ws.api.SOAPVersion.getMessageFactory(SOAPVersion.java:221)
at com.sun.xml.ws.api.message.saaj.SAAJFactory.readAsSOAPMessage(SAAJFactory.java:275)
at com.sun.xml.ws.api.message.saaj.SAAJFactory.readAsSAAJ(SAAJFactory.java:205)
at com.sun.xml.ws.api.message.saaj.SAAJFactory.read(SAAJFactory.java:194)
at com.sun.xml.ws.message.AbstractMessageImpl.toSAAJ(AbstractMessageImpl.java:199)
at com.sun.xml.ws.api.message.MessageWrapper.readAsSOAPMessage(MessageWrapper.java:160)
at com.sun.xml.ws.handler.SOAPMessageContextImpl.getMessage(SOAPMessageContextImpl.java:86)
并且阻塞线程在同一个地方运行
"[1432628598653] POST /services/signin HTTP/1.0" Id=1990 RUNNABLE
at java.util.zip.ZipFile.getEntry(ZipFile.java:304)
- locked java.util.jar.JarFile@464f9f8
at java.util.jar.JarFile.getEntry(JarFile.java:226)
at java.util.jar.JarFile.getJarEntry(JarFile.java:209)
at sun.misc.URLClassPath$JarLoader.getResource(URLClassPath.java:840)
at sun.misc.URLClassPath$JarLoader.findResource(URLClassPath.java:818)
at sun.misc.URLClassPath$1.next(URLClassPath.java:226)
at sun.misc.URLClassPath$1.hasMoreElements(URLClassPath.java:236)
at java.net.URLClassLoader$3$1.run(URLClassLoader.java:583)
at java.net.URLClassLoader$3$1.run(URLClassLoader.java:581)
at java.security.AccessController.doPrivileged(Native Method)
at java.net.URLClassLoader$3.next(URLClassLoader.java:580)
at java.net.URLClassLoader$3.hasMoreElements(URLClassLoader.java:605)
at sun.misc.CompoundEnumeration.next(CompoundEnumeration.java:45)
at sun.misc.CompoundEnumeration.hasMoreElements(CompoundEnumeration.java:54)
at sun.misc.CompoundEnumeration.next(CompoundEnumeration.java:45)
at sun.misc.CompoundEnumeration.hasMoreElements(CompoundEnumeration.java:54)
at com.sun.xml.ws.util.ServiceFinder$LazyIterator.hasNext(ServiceFinder.java:443)
at com.sun.xml.ws.util.ServiceFinder$CompositeIterator.hasNext(ServiceFinder.java:390)
at com.sun.xml.ws.api.message.saaj.SAAJFactory.read(SAAJFactory.java:190)
at com.sun.xml.ws.message.AbstractMessageImpl.toSAAJ(AbstractMessageImpl.java:199)
at com.sun.xml.ws.api.message.MessageWrapper.readAsSOAPMessage(MessageWrapper.java:160)
at com.sun.xml.ws.handler.SOAPMessageContextImpl.getMessage(SOAPMessageContextImpl.java:86)
我们的应用程序是否以错误的方式做某事?是否有避免在类加载器中阻塞的解决方法?