Uploaded image for project: 'JDK'
  1. JDK
  2. JDK-8035424

Performance problem in sun.reflect.generics.parser.SignatureParser

    XMLWordPrintable

Details

    Backports

      Description

        FULL PRODUCT VERSION :
        Java HotSpot(TM) Server VM (24.51-b03) for linux-x86 JRE (1.7.0_51-b13), built on Dec 18 2013 18:45:30 by "java_re" with gcc 4.3.0 20080428 (Red Hat 4.3.0-8)


        ADDITIONAL OS VERSION INFORMATION :
        Linux Centos 6.x
        Windows 7

        A DESCRIPTION OF THE PROBLEM :
        We detect performance degradation for web-application using JAXB and Jackson(JSON) libraries. The following report is from Java Mission Control tool:

        Stack Trace Count
        java.lang.ArrayIndexOutOfBoundsException.<init>(String) 204 650
        sun.reflect.generics.parser.SignatureParser.current() 195 430
        sun.reflect.generics.parser.SignatureParser.parseZeroOrMoreThrowsSignatures() 195 430

        The ArrayIndexOutOfBoundsException is thrown about 500 instance per second.

        There are two strange methods in SignatureParser:

               84 private char getNext(){
               85 assert(index <= input.length);
               86 try {
               87 return input[index++];
               88 } catch (ArrayIndexOutOfBoundsException e) { return EOI;}
               89 }
               90
               91 // returns current element of the input
               92 private char current(){
               93 assert(index <= input.length);
               94 try {
               95 return input[index];
               96 } catch (ArrayIndexOutOfBoundsException e) { return EOI;}
               97 }

        So, as in "Effective java" book recommendation:
        "57. Use exceptions only for exceptional conditions
        Do not use catch block to implement regular control flow.
        Actually, executing catch block is 100 times slower than normal block."

        The following code could be more effective:

         private char getNext(){
            assert(index <= input.length);
           if(index<input.length){
             return input[index++];
           }else{
             return EOI;
           }
        }
         
         // returns current element of the input
        private char current(){
            assert(index <= input.length);
           if(index<input.length){
             return input[index];
           }else{
             return EOI;
           }
        }


        EXPECTED VERSUS ACTUAL BEHAVIOR :
        EXPECTED -
        No swallowed exception, better performance
        ACTUAL -
        Too many internal Exceptions, bad performance.

        REPRODUCIBILITY :
        This bug can be reproduced always.

        CUSTOMER SUBMITTED WORKAROUND :
        Reuse JAXB Context and jackson Object Mapper to avoid repeated annotation introspection - this minimalists the number of parser calls and thrown exceptions.

        Attachments

          Issue Links

            Activity

              People

                kravikumar Kiran Sidhartha Ravikumar (Inactive)
                webbuggrp Webbug Group
                Votes:
                0 Vote for this issue
                Watchers:
                9 Start watching this issue

                Dates

                  Created:
                  Updated:
                  Resolved: