High lock contention in sun.misc.URLClassPath.getLoader under JAXB unmarshaller

旧城冷巷雨未停 提交于 2021-01-27 06:48:12

问题


We have this particular piece of code running on weblogic, its function is to return a java object specific to input class from XML input string. The code itself will be used by multiple of threads (50+).

public static Object toXMLObject(String XMLString, Class xmlClass)
        throws Exception {

    StringReader strReader = null;

    try {

        JAXBContext context = JAXBContexts.getJAXBContext(xmlClass); //Cached JAXBContext
        Unmarshaller unmarshaller = context.createUnmarshaller();

        strReader = new StringReader(XMLString);

        return unmarshaller.unmarshal(strReader);

    } catch(Exception e){
        throw e;
    } finally {
        if(strReader != null){
            strReader.close();
        }
    }

}

What we've seen from thread dump is that multiple of threads (51 threads) trying to lock on a single object

    ExecuteThread: '52' for queue: 'automation'" daemon prio=3 tid=0x0000000103bcf800 nid=0x1a4 waiting for monitor entry [0xfffffffac2cfb000]**
     java.lang.Thread.State: BLOCKED (on object monitor)
at sun.misc.URLClassPath.getLoader(URLClassPath.java:279)
- locked <0xfffffffb89f00ed8> (a sun.misc.URLClassPath)
at sun.misc.URLClassPath.findResource(URLClassPath.java:145)
at java.net.URLClassLoader$2.run(URLClassLoader.java:385)
at java.security.AccessController.doPrivileged(Native Method)
at java.net.URLClassLoader.findResource(URLClassLoader.java:382)
at java.lang.ClassLoader.getResource(ClassLoader.java:1002)
at java.lang.ClassLoader.getResource(ClassLoader.java:997)
at java.lang.ClassLoader.getResource(ClassLoader.java:997)
at weblogic.utils.classloaders.GenericClassLoader.getResourceInternal(GenericClassLoader.java:168)
at weblogic.utils.classloaders.GenericClassLoader.getResource(GenericClassLoader.java:182)
at weblogic.utils.classloaders.FilteringClassLoader.getResourceInternal(FilteringClassLoader.java:129)
at weblogic.utils.classloaders.GenericClassLoader.getResourceInternal(GenericClassLoader.java:154)
at weblogic.utils.classloaders.GenericClassLoader.getResource(GenericClassLoader.java:182)
at java.lang.ClassLoader.getResourceAsStream(ClassLoader.java:1192)
at org.apache.xerces.parsers.SecuritySupport$6.run(Unknown Source)
at java.security.AccessController.doPrivileged(Native Method)
at org.apache.xerces.parsers.SecuritySupport.getResourceAsStream(Unknown Source)
at org.apache.xerces.parsers.ObjectFactory.findJarServiceProvider(Unknown Source)
at org.apache.xerces.parsers.ObjectFactory.createObject(Unknown Source)
at org.apache.xerces.parsers.ObjectFactory.createObject(Unknown Source)
at org.apache.xerces.parsers.SAXParser. (Unknown Source)
at org.apache.xerces.parsers.SAXParser. (Unknown Source)
at org.apache.xerces.jaxp.SAXParserImpl$JAXPSAXParser. (Unknown Source)
at org.apache.xerces.jaxp.SAXParserImpl. (Unknown Source)
at org.apache.xerces.jaxp.SAXParserFactoryImpl.newSAXParser(Unknown Source)
at weblogic.xml.jaxp.RegistrySAXParser. (RegistrySAXParser.java:65)
at weblogic.xml.jaxp.RegistrySAXParser. (RegistrySAXParser.java:46)
at weblogic.xml.jaxp.RegistrySAXParserFactory.newSAXParser(RegistrySAXParserFactory.java:91)
at javax.xml.bind.helpers.AbstractUnmarshallerImpl.getXMLReader(AbstractUnmarshallerImpl.java:86)
at javax.xml.bind.helpers.AbstractUnmarshallerImpl.unmarshal(AbstractUnmarshallerImpl.java:137)
at javax.xml.bind.helpers.AbstractUnmarshallerImpl.unmarshal(AbstractUnmarshallerImpl.java:194)
at com.util.XMLParserUtil.toXMLObject(XMLParserUtil.java:699)

  ExecuteThread: '78' for queue: 'automation'" daemon prio=3 tid=0x000000010363b800 nid=0x1be waiting for monitor entry [0xfffffffabf8fb000]**
   java.lang.Thread.State: BLOCKED (on object monitor)
at sun.misc.URLClassPath.getLoader(URLClassPath.java:279)
- waiting to lock <0xfffffffb89f00ed8> (a sun.misc.URLClassPath)
at sun.misc.URLClassPath.findResource(URLClassPath.java:145)
at java.net.URLClassLoader$2.run(URLClassLoader.java:385)
at java.security.AccessController.doPrivileged(Native Method)
at java.net.URLClassLoader.findResource(URLClassLoader.java:382)
at java.lang.ClassLoader.getResource(ClassLoader.java:1002)
at java.lang.ClassLoader.getResource(ClassLoader.java:997)
at java.lang.ClassLoader.getResource(ClassLoader.java:997)
at weblogic.utils.classloaders.GenericClassLoader.getResourceInternal(GenericClassLoader.java:168)
at weblogic.utils.classloaders.GenericClassLoader.getResource(GenericClassLoader.java:182)
at weblogic.utils.classloaders.FilteringClassLoader.getResourceInternal(FilteringClassLoader.java:129)
at weblogic.utils.classloaders.GenericClassLoader.getResourceInternal(GenericClassLoader.java:154)
at weblogic.utils.classloaders.GenericClassLoader.getResource(GenericClassLoader.java:182)
at java.lang.ClassLoader.getResourceAsStream(ClassLoader.java:1192)
at org.apache.xerces.parsers.SecuritySupport$6.run(Unknown Source)
at java.security.AccessController.doPrivileged(Native Method)
at org.apache.xerces.parsers.SecuritySupport.getResourceAsStream(Unknown Source)
at org.apache.xerces.parsers.ObjectFactory.findJarServiceProvider(Unknown Source)
at org.apache.xerces.parsers.ObjectFactory.createObject(Unknown Source)
at org.apache.xerces.parsers.ObjectFactory.createObject(Unknown Source)
at org.apache.xerces.parsers.SAXParser. (Unknown Source)
at org.apache.xerces.parsers.SAXParser. (Unknown Source)
at org.apache.xerces.jaxp.SAXParserImpl$JAXPSAXParser. (Unknown Source)
at org.apache.xerces.jaxp.SAXParserImpl. (Unknown Source)
at org.apache.xerces.jaxp.SAXParserFactoryImpl.newSAXParser(Unknown Source)
at weblogic.xml.jaxp.RegistryXMLReader.getXMLReader(RegistryXMLReader.java:523)
at weblogic.xml.jaxp.RegistryXMLReader.getXMLReaderInternal(RegistryXMLReader.java:453)
at weblogic.xml.jaxp.RegistryXMLReader.parse(RegistryXMLReader.java:158)
at com.sun.xml.bind.v2.runtime.unmarshaller.UnmarshallerImpl.unmarshal0(UnmarshallerImpl.java:211)
at com.sun.xml.bind.v2.runtime.unmarshaller.UnmarshallerImpl.unmarshal(UnmarshallerImpl.java:184)
at javax.xml.bind.helpers.AbstractUnmarshallerImpl.unmarshal(AbstractUnmarshallerImpl.java:137)
at javax.xml.bind.helpers.AbstractUnmarshallerImpl.unmarshal(AbstractUnmarshallerImpl.java:194)
at com.util.XMLParserUtil.toXMLObject(XMLParserUtil.java:699)

Did we implement JAXB code properly? How could we overcome this problem. Ps. we've overriden JAXP with latest version (1.4.6) on JDK1.6.0_33


回答1:


You could try doing the following:

package forum11344031;

import java.io.StringReader;
import javax.xml.bind.*;
import javax.xml.stream.*;

public class Demo {

    private static final XMLInputFactory XIF = XMLInputFactory.newFactory();

    public static Object toXMLObject(String XMLString, Class xmlClass)
            throws Exception {
        Object o;
        StringReader strReader = null;
        try {
            JAXBContext context = JAXBContexts.getJAXBContext(xmlClass); //Cached JAXBContext
            Unmarshaller unmarshaller = context.createUnmarshaller();

            strReader = new StringReader(XMLString);
            XMLStreamReader xmlStreamReader = XIF.createXMLStreamReader(strReader);
            o = unmarshaller.unmarshal(xmlStreamReader);
            xmlStreamReader.close();
        } catch(Exception e){
            throw e;
        } finally {
            if(strReader != null){
                strReader.close();
            }
        }
        return o;
    }

}



回答2:


What about this one, Will this help?

"-Djavax.xml.parsers.SAXParserFactory=org.apache.xerces.jaxp.SAXParserFactoryImpl"

according to slide#49 http://www.slideshare.net/sjlee0/robust-and-scalable-concurrent-programming-lesson-from-the-trenches




回答3:


Thanks. I found very useful the presentation "Robust and Scalable Concurrent Programming". I have successfully tested the solution of the pages 49-50. Now I don't see locks in the method ObjectFactory.createObject.

The magic solution is to reserve a different SAXParser for each thread.

static private final ThreadLocal<SAXParser> sps = new ThreadLocal<SAXParser>();

public static SAXParser getParser() throws ParserConfigurationException, SAXException {
    SAXParser parser = sps.get();
    if (parser == null) {
        parser = spf.newSAXParser();
        sps.set(parser);
    }
    return parser;
}


来源:https://stackoverflow.com/questions/11344031/high-lock-contention-in-sun-misc-urlclasspath-getloader-under-jaxb-unmarshaller

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!