OsgiLocator causes huge performance bottlenecks
-----------------------------------------------
Key: SMX4-803
URL: https://issues.apache.org/jira/browse/SMX4-803
Project: ServiceMix 4
Issue Type: Improvement
Components: Bundles
Reporter: Willem Jiang
Assignee: Willem Jiang
Fix For: specs-1.8.0
org.apache.servicemix.specs.locator.OsgiLocator is inlined into many SMX specs
bundles. If someone uese any of these APIs heavily, OsgiLocator causes serious
performance degradation. In most cases this happens if somebody uses the given
API incorrectly and does not reuse objects (factories). In our case it is CXF's
SAAJ IN interceptor that most probably incorrectly uses SAAJ API
(MessageFactory).
Anyway, the problem is that:
1) OsgiLocator's methods are all static synchronized. If many threads try to
get a SAAJ factory, they start jamming in locate(String factoryId) as it is
synchronized. For example this CXF stuff might cause it:
{code}
at javax.xml.soap.FactoryFinder.find(FactoryFinder.java:86)
at javax.xml.soap.MessageFactory.newInstance(MessageFactory.java:85)
at
org.apache.cxf.binding.soap.saaj.SAAJInInterceptor.getFactory(SAAJInInterceptor.java:88)
- locked [0x00002aac03ea1628] (a
org.apache.cxf.binding.soap.saaj.SAAJInInterceptor)
at
org.apache.cxf.binding.soap.saaj.SAAJInInterceptor.handleMessage(SAAJInInterceptor.java:100)
at
org.apache.cxf.binding.soap.saaj.SAAJInInterceptor.handleMessage(SAAJInInterceptor.java:71)
at
org.apache.cxf.phase.PhaseInterceptorChain.doIntercept(PhaseInterceptorChain.java:243)
- locked [0x00002aac07fb9908] (a org.apache.cxf.phase.PhaseInterceptorChain)
at org.apache.cxf.endpoint.ClientImpl.onMessage(ClientImpl.java:737)
at
com.sabre.cxf.extensions.transport.http.JettyContentExchange.doTaskCompleted(JettyContentExchange.java:244)
at
com.sabre.cxf.extensions.transport.http.JettyContentExchange.onResponseComplete(JettyContentExchange.java:107)
at
org.mortbay.jetty.client.HttpExchange$Listener.onResponseComplete(HttpExchange.java:730)
at org.mortbay.jetty.client.HttpExchange.setStatus(HttpExchange.java:194)
at
org.mortbay.jetty.client.HttpConnection$Handler.messageComplete(HttpConnection.java:517)
at org.mortbay.jetty.HttpParser.parseNext(HttpParser.java:761)
at org.mortbay.jetty.HttpParser.parseAvailable(HttpParser.java:212)
at org.mortbay.jetty.client.HttpConnection.handle(HttpConnection.java:245)
at org.mortbay.io.nio.SelectChannelEndPoint.run(SelectChannelEndPoint.java:410)
at org.mortbay.thread.QueuedThreadPool$PoolThread.run(QueuedThreadPool.java:582)
{code}
In order to get rid of this issue OSGiLocator should start using a
ReentrantReadWriteLock instead of the synchronized keyword. Attached is a
modified version OSGi locator that uses ReentrantReadWriteLock . However, a
problem is still observed ...See #2.
2) After OSGiLocator was hacked, a bottleneck was identified deeper - in the
bundle classloader:
{code}
at sun.misc.Launcher$AppClassLoader.loadClass(Launcher.java:293)
- waiting to lock [0x00002aabf6230d80] (a sun.misc.Launcher$AppClassLoader)
at java.lang.ClassLoader.loadClass(ClassLoader.java:248)
at
org.eclipse.osgi.internal.loader.BundleLoader.findClassInternal(BundleLoader.java:438)
at
org.eclipse.osgi.internal.loader.BundleLoader.findClass(BundleLoader.java:422)
at
org.eclipse.osgi.internal.loader.BundleLoader.findClass(BundleLoader.java:410)
at
org.eclipse.osgi.internal.baseadaptor.DefaultClassLoader.loadClass(DefaultClassLoader.java:107)
at java.lang.ClassLoader.loadClass(ClassLoader.java:248)
at
org.eclipse.osgi.internal.loader.BundleLoader.loadClass(BundleLoader.java:338)
at
org.eclipse.osgi.framework.internal.core.BundleHost.loadClass(BundleHost.java:232)
at
org.eclipse.osgi.framework.internal.core.AbstractBundle.loadClass(AbstractBundle.java:1197)
at
org.apache.servicemix.specs.locator.Activator$BundleFactoryLoader.call(Activator.java:149)
at
org.apache.servicemix.specs.locator.Activator$BundleFactoryLoader.call(Activator.java:131)
at org.apache.servicemix.specs.locator.OsgiLocator.locate(OsgiLocator.java:75)
at javax.xml.soap.FactoryFinder.find(FactoryFinder.java:86)
at javax.xml.soap.MessageFactory.newInstance(MessageFactory.java:85)
at
org.apache.cxf.binding.soap.saaj.SAAJInInterceptor.getFactory(SAAJInInterceptor.java:88)
- locked [0x00002aac03ea1628] (a
org.apache.cxf.binding.soap.saaj.SAAJInInterceptor)
at
org.apache.cxf.binding.soap.saaj.SAAJInInterceptor.handleMessage(SAAJInInterceptor.java:100)
at
org.apache.cxf.binding.soap.saaj.SAAJInInterceptor.handleMessage(SAAJInInterceptor.java:71)
at
org.apache.cxf.phase.PhaseInterceptorChain.doIntercept(PhaseInterceptorChain.java:243)
- locked [0x00002aac07fb9908] (a org.apache.cxf.phase.PhaseInterceptorChain)
at org.apache.cxf.endpoint.ClientImpl.onMessage(ClientImpl.java:737)
at
com.sabre.cxf.extensions.transport.http.JettyContentExchange.doTaskCompleted(JettyContentExchange.java:244)
at
com.sabre.cxf.extensions.transport.http.JettyContentExchange.onResponseComplete(JettyContentExchange.java:107)
at
org.mortbay.jetty.client.HttpExchange$Listener.onResponseComplete(HttpExchange.java:730)
at org.mortbay.jetty.client.HttpExchange.setStatus(HttpExchange.java:194)
at
org.mortbay.jetty.client.HttpConnection$Handler.messageComplete(HttpConnection.java:517)
at org.mortbay.jetty.HttpParser.parseNext(HttpParser.java:761)
at org.mortbay.jetty.HttpParser.parseAvailable(HttpParser.java:212)
at org.mortbay.jetty.client.HttpConnection.handle(HttpConnection.java:245)
at org.mortbay.io.nio.SelectChannelEndPoint.run(SelectChannelEndPoint.java:410)
at org.mortbay.thread.QueuedThreadPool$PoolThread.run(QueuedThreadPool.java:582)
{code}
It might be reasonable to change Activator.BundleFactoryLoader to cache the
implementation class.
--
This message is automatically generated by JIRA.
For more information on JIRA, see: http://www.atlassian.com/software/jira