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

Revisit the number of AWT loggers to reduce the memory usage

    • generic
    • generic

      AWT statically creates a number of loggers. Running a simple Framer application (awt helloworld) with JDK 7 b70 creates 79 loggers on solaris-i586 and 34 loggers on windows-i586. SwingSet2 creates a total of 85 loggers including a few non-awt ones on solaris-i586 and 35 on windows-i586).

      Each class has its own logger which isn't necessary. Instead, it increases the memory usage and these loggers are created at startup. Please revisit the number of AWT loggers needed. Also recommend to create loggers lazily if possible.

      jmap -histo output on solaris-i586:

        36: 79 5056 java.util.logging.Logger
        49: 105 2520 java.util.logging.LogManager$LogNode
        52: 80 1920 java.util.logging.LogManager$3
       169: 9 216 java.util.logging.Level
       241: 1 112 java.util.logging.LogManager$Cleaner
       313: 1 64 java.util.logging.LogManager$RootLogger
       390: 1 40 java.util.logging.LogManager
       428: 2 32 [Ljava.util.logging.Handler;
       495: 1 24 java.util.logging.LoggingPermission
       524: 1 16 java.util.logging.LogManager$2
       574: 1 8 java.util.logging.LogManager$1

      jmap -histo output on windows-i586:
        40: 34 2176 java.util.logging.Logger
        52: 49 1176 java.util.logging.LogManager$LogNode
        62: 35 840 java.util.logging.LogManager$3
       134: 9 216 java.util.logging.Level
       179: 1 112 java.util.logging.LogManager$Cleaner
       246: 1 64 java.util.logging.LogManager$RootLogger
       308: 1 40 java.util.logging.LogManager
       330: 2 32 [Ljava.util.logging.Handler;
       364: 1 24 java.util.logging.LoggingPermission
       440: 1 16 java.util.logging.LogManager$2
       500: 1 8 java.util.logging.LogManager$1
      Most of the logging code in AWT/2D looks like this:

      private static final Logger log = Logger.getLogger("java.awt.AWTEvent");
      ....

         if (log.isLoggable(Level.FINE)) {
            log.log(Level.FINE, "AWTEvent.get_InputEvent_CanAccessSystemClipboard() got SecurityException ", e);
         }

      1) the Logger is created in the static initializer even though no log message is output.
      2) the logging code tests if the log message is filtered or not before making the log method call.

      This is done for performance reason since it wants to avoid the cost in constructing the parameters.

      3) Each class with the logging code has at least one logger created.

      We should consider having one logger for each core component instead of 1 or more for each class. Or consider lazy initializing all these loggers.

      Something like this:

      // Add a new method to log fine message to the java.awt.AWTEvent logger
      private static void fine(String msg, Throwable t) {
          if (log == null) {
              log = PlatformLogger.getLogger("java.awt.AWTEvent");
          }
          if (log.isLoggable(PlatformLogger.FINE)) {
              log.fine(msg, t);
          }
      }
       
      Change the above logging code to just call this method.

            Unassigned Unassigned
            mchung Mandy Chung (Inactive)
            Votes:
            0 Vote for this issue
            Watchers:
            2 Start watching this issue

              Created:
              Updated:
              Imported:
              Indexed: