<rt id="bn8ez"></rt>
<label id="bn8ez"></label>

  • <span id="bn8ez"></span>

    <label id="bn8ez"><meter id="bn8ez"></meter></label>

    posts - 42,comments - 83,trackbacks - 0
            這兩天有客戶跟我說了個問題,說他們發(fā)現(xiàn)weblogic不停的load class,最后線程都掛在了Zip Entry操作上。讓他們做了thread dump, 開始以為跟JDK的IO性能有關(guān)系,因為我曾經(jīng)在HP\AIX上都碰到過線程掛起在zip操作上的問題,最終客戶通過調(diào)整OS參數(shù)后,問題得到解決。但在拿到thread dump后, 發(fā)現(xiàn)問題不是他們說的那樣,thread trace如下:

    "ExecuteThread: '6' for queue: 'Out.Thread Pool'" daemon prio=5 tid=0005ff90 nid=54 lwp_id=1885955 waiting for monitor entry [0x239fa000..0x239f94f0]
     at java.util.zip.ZipFile.getEntry(ZipFile.java:161)
     - waiting to lock <35da8e78> (a sun.net.www.protocol.jar.URLJarFile)
     at java.util.jar.JarFile.getEntry(JarFile.java:194)
     at sun.net.www.protocol.jar.URLJarFile.getEntry(URLJarFile.java:89)
     at sun.net.www.protocol.jar.JarURLConnection.connect(JarURLConnection.java:95)
     at sun.net.www.protocol.jar.JarURLConnection.getInputStream(JarURLConnection.java:107)
     at java.net.URL.openStream(URL.java:913)
     at java.lang.ClassLoader.getResourceAsStream(ClassLoader.java:997)
     at javax.xml.parsers.FactoryFinder.find(FactoryFinder.java:160)
     at javax.xml.parsers.SAXParserFactory.newInstance(SAXParserFactory.java:87)
     at org.dom4j.io.JAXPHelper.createXMLReader(JAXPHelper.java:46)
     at org.dom4j.io.SAXHelper.createXMLReaderViaJAXP(SAXHelper.java:125)
     at org.dom4j.io.SAXHelper.createXMLReader(SAXHelper.java:78)
     at org.dom4j.io.SAXReader.createXMLReader(SAXReader.java:894)
     at org.dom4j.io.SAXReader.getXMLReader(SAXReader.java:715)
     at org.dom4j.io.SAXReader.read(SAXReader.java:435)
     at org.dom4j.DocumentHelper.parseText(DocumentHelper.java:278)
     ......

            我們可以看看SAXParserFactory.newInstance()的實現(xiàn),

     1     public static SAXParserFactory newInstance()
     2         throws FactoryConfigurationError
     3     {
     4         try
     5         {
     6             return (SAXParserFactory)FactoryFinder.find("javax.xml.parsers.SAXParserFactory""org.apache.xerces.jaxp.SAXParserFactoryImpl");
     7         }
     8         catch(FactoryFinder.ConfigurationError configurationerror)
     9         {
    10             throw new FactoryConfigurationError(configurationerror.getException(), configurationerror.getMessage());
    11         }
    12     }

            再來看看FactoryFinder.find()的實現(xiàn),

     1     static Object find(String s, String s1)
     2         throws ConfigurationError
     3     {
     4         debugPrintln("debug is on");
     5         ClassLoader classloader = findClassLoader();
     6         try
     7         {
     8             String s2 = System.getProperty(s);
     9             if(s2 != null)
    10             {
    11                 debugPrintln("found system property " + s2);
    12                 return newInstance(s2, classloader);
    13             }
    14         }
    15         catch(SecurityException _ex) { }
    16         try
    17         {
    18             String s3 = System.getProperty("java.home");
    19             String s5 = s3 + File.separator + "lib" + File.separator + "jaxp.properties";
    20             File file = new File(s5);
    21             if(file.exists())
    22             {
    23                 Properties properties = new Properties();
    24                 properties.load(new FileInputStream(file));
    25                 String s7 = properties.getProperty(s);
    26                 debugPrintln("found java.home property " + s7);
    27                 return newInstance(s7, classloader);
    28             }
    29         }
    30         catch(Exception exception) { }
    31         String s4 = "META-INF/services/" + s;
    32         try
    33         {
    34             java.io.InputStream inputstream = null;
    35             if(classloader == null)
    36                 inputstream = ClassLoader.getSystemResourceAsStream(s4);
    37             else
    38                 inputstream = classloader.getResourceAsStream(s4);
    39             if(inputstream != null)
    40             {
    41                 debugPrintln("found " + s4);
    42                 BufferedReader bufferedreader;
    43                 try
    44                 {
    45                     bufferedreader = new BufferedReader(new InputStreamReader(inputstream, "UTF-8"));
    46                 }
    47                 catch(UnsupportedEncodingException _ex)
    48                 {
    49                     bufferedreader = new BufferedReader(new InputStreamReader(inputstream));
    50                 }
    51                 String s6 = bufferedreader.readLine();
    52                 bufferedreader.close();
    53                 if(s6 != null && !"".equals(s6))
    54                 {
    55                     debugPrintln("loaded from services: " + s6);
    56                     return newInstance(s6, classloader);
    57                 }
    58             }
    59         }
    60         catch(Exception exception1) { }
    61         if(s1 == null)
    62         {
    63             throw new ConfigurationError("Provider for " + s + " cannot be found"null);
    64         } else
    65         {
    66             debugPrintln("loaded from fallback value: " + s1);
    67             return newInstance(s1, classloader);
    68         }
    69     }
    70 

            看看兩個方法的具體實現(xiàn),這個問題基本一目了然了吧。 在我們要解析XML文件的時候,我們首先需要從parser factory獲取一個parser實例,但parser factroy是什么? 我們需要去查找。仔細看一下這個查找順序:
    1:System property, JVM中是否定義了javax.xml.parsers.SAXParserFactory,這個可以通過-D設(shè)定
    2:$JRE_HOME/ lib/jaxp.properties文件,是否存在javax.xml.parsers.SAXParserFactory鍵值對
    3:xerces.jar文件的meta-inf/services/javax.xml.parsers.SAXParserFactory文件是否有值
    4:當(dāng)前classloader,是否存在org.apache.xerces.jaxp.SAXParserFactoryImpl,

            從thread dump可以看到,客戶線程掛在了3上,因為1, 2條件不成立,所以走到了3, 而3每次都要打開jar文件,最終看到線程都停在了java.util.zip.ZipFile.getEntry()上。 解決方法:
    1:啟動JVM的時候,增加-Djavax.xml.parsers.SAXParserFactory=***
    2::在$JRE_HOME/lib/增加jaxp.properties文件,其中定義javax.xml.parsers.SAXParserFactory=***
    3:用展開的xerces.jar文件代替原有的jar文件

            客戶同時提及了另外一個問題:我們有自己的parser factory, 為什么最后用了weblogic的? 而且不停的load class? Trace 如下:

    "ExecuteThread: '42' for queue: 'OCS.Thread.Pool'" daemon prio=5 tid=004ca430 nid=245 lwp_id=1886146 waiting for monitor entry [0x1d9ba000..0x1d9ba4f0]
     at java.lang.ClassLoader.loadClass(ClassLoader.java:278)
     - waiting to lock <364cdf18> (a weblogic.utils.classloaders.GenericClassLoader)
     at java.lang.ClassLoader.loadClass(ClassLoader.java:235)
     at weblogic.utils.classloaders.GenericClassLoader.loadClass(GenericClassLoader.java:224)
     at javax.xml.parsers.FactoryFinder.newInstance(FactoryFinder.java:93)
     at javax.xml.parsers.FactoryFinder.find(FactoryFinder.java:174)
     ......

            其實在上面的分析中可以看到,前三項中都沒有找到parser factory, 那我們只能在當(dāng)前class loader中去查找,并創(chuàng)建instance。因為你的應(yīng)用部署在weblogic上, weblogic的classloader機制是, 所有的應(yīng)用class loader都繼承于weblogic application class loader, 所以你會看到weblogic class loader在trace中。但為什么不停的在class loader呢?其實看看JDK文檔,并看看JDK的實現(xiàn)就能知道,
    protected Class<?> loadClass(String name,
    boolean resolve)
    throws ClassNotFoundException
    Loads the class with the specified binary name. The default implementation of this method searches for classes in the following order:

     

    1. Invoke findLoadedClass(String) to check if the class has already been loaded.

    2. Invoke the loadClass method on the parent class loader. If the parent is null the class loader built-in to the virtual machine is used, instead.

    3. Invoke the findClass(String) method to find the class.

    If the class was found using the above steps, and the resolve flag is true, this method will then invoke the resolveClass(Class) method on the resulting Class object.



     1     protected synchronized Class loadClass(String name, boolean resolve)
     2     throws ClassNotFoundException
     3     {
     4     // First, check if the class has already been loaded
     5     Class c = findLoadedClass(name);
     6     if (c == null) {
     7         try {
     8         if (parent != null) {
     9             c = parent.loadClass(name, false);
    10         } else {
    11             c = findBootstrapClass0(name);
    12         }
    13         } catch (ClassNotFoundException e) {
    14             // If still not found, then invoke findClass in order
    15             // to find the class.
    16             c = findClass(name);
    17         }
    18     }
    19     if (resolve) {
    20         resolveClass(c);
    21     }
    22     return c;
    23     }

            看看,其實能看到loadclass(),并不能說class loader一定在load class,更多的時候,他們是在find loaded class,否則怎么去創(chuàng)建對象?







    posted on 2008-09-13 21:57 走走停停又三年 閱讀(2961) 評論(1)  編輯  收藏 所屬分類: Weblogic

    FeedBack:
    # re: 關(guān)于weblogic中使用Dom4j、Xerces導(dǎo)致執(zhí)行線程掛起的問題
    2011-09-21 15:44 | ,,,
    主站蜘蛛池模板: 亚洲视频中文字幕| 国产AV无码专区亚洲AV手机麻豆| 亚洲AV无码久久精品成人 | 亚洲 自拍 另类小说综合图区| 久久精品国产99国产精品亚洲| 永久免费视频网站在线观看| 亚洲男人的天堂在线播放| 免费A级毛片无码A∨| 久久久国产精品亚洲一区| 日本高清在线免费| 日韩亚洲国产高清免费视频| 在线观看成人免费| 羞羞漫画页面免费入口欢迎你| www.亚洲色图.com| 无码一区二区三区免费| 亚洲国产综合精品| 成在线人永久免费视频播放| 农村寡妇一级毛片免费看视频| 日本亚洲国产一区二区三区| 久久免费国产精品一区二区| 亚洲国产综合在线| 成人人观看的免费毛片| 成年免费a级毛片| 亚洲国产精品无码专区| 一色屋成人免费精品网站| 亚洲AV无码一区二区乱子仑 | 亚洲日韩精品一区二区三区| 59pao成国产成视频永久免费| 亚洲第一男人天堂| 久久久久亚洲精品中文字幕| 精品一区二区三区无码免费视频| 亚洲AV成人影视在线观看| xvideos亚洲永久网址| 四虎影视成人永久免费观看视频 | 久久精品亚洲综合专区| 美女网站免费福利视频| 免费视频精品一区二区| 久久亚洲私人国产精品vA| 免费欧洲毛片A级视频无风险| 中文字幕无码日韩专区免费| 在线亚洲午夜片AV大片|