glassfish
  1. glassfish
  2. GLASSFISH-20670

Performance problem in getInitParameter and getInitParameterNames() of org.apache.catalina.core.ApplicationContext (glassfish version), which are called very often by JSF frameworks

    Details

    • Type: Bug Bug
    • Status: Resolved
    • Priority: Major Major
    • Resolution: Fixed
    • Affects Version/s: 3.1.2.2, 4.0_b89_RC5
    • Fix Version/s: 4.1_b08
    • Component/s: performance, web_container
    • Labels:
      None

      Description

      During performance tests (multiple parallel threads) of our enterprise application we discovered that 62% of time is spent in org.apache.catalina.core.ApplicationContext.mergeParameters.

          • Background:
            The calls to this method have origin in JSF stack - there are calls to context.getExternalContext().getInitParameter() from
            javax.faces.component.UIComponent.pushComponentToEL
            javax.faces.component.UIComponent.popComponentFromEL
            In default JSF implementation provided with glassfish the value for UIComponent.HONOR_CURRENT_COMPONENT_ATTRIBUTES_PARAM_NAME is obtained (without caching) for each call withing these methods.
          • Source of problem:
            The mergeParameters, which is internally called from getInitParameter and getInitParameterNames(), is synchronized.
            I analysed source of this class and believe that synchronization in this area could be improved.
            The problem was discovered during tests with glassfish 3.1.1.2, but it seems that other versions including trunk are affected as well.
          • Suggested solution:
            The problem seems to be easy to fix.

      This is the original body for mergeParameters:
      private synchronized void mergeParameters() {
      if (parametersMerged)

      { return; }

      [...]

      parametersMerged = true;
      }

      As:
      - this is the only synchronized method and there no "synchronized (this)" in this class
      - the field parametersMerged is assigned a value only in mergeParameters (last line) and at initialization (private volatile boolean parametersMerged = false
      - after the first execution of mergeParameters the field parametersMerged will never be assigned any value (especially false) and other calls to mergeParameters are waste of time.
      - the field parametersMerged is volatile
      the problem could be successfully solved by moving the synchronization to inside of the method and double checking the initial condition:

      private void mergeParameters() {
      if (parametersMerged) { return; }

      synchronized(this){
      if (parametersMerged)

      { return; }

      [...]

      parametersMerged = true;
      }
      }

        Activity

          People

          • Assignee:
            Scott Oaks
            Reporter:
            lsxx
          • Votes:
            0 Vote for this issue
            Watchers:
            4 Start watching this issue

            Dates

            • Created:
              Updated:
              Resolved: