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.