JDK-6603256 : Startup: Defer initialization of DropTarget's flavorMap
  • Type: Enhancement
  • Component: client-libs
  • Sub-Component: java.awt
  • Affected Version: 7
  • Priority: P2
  • Status: Closed
  • Resolution: Fixed
  • OS: generic
  • CPU: generic
  • Submitted: 2007-09-11
  • Updated: 2011-05-17
  • Resolved: 2011-05-17
The Version table provides details related to the release that this issue/RFE will be addressed.

Unresolved : Release in which this issue/RFE will be addressed.
Resolved: Release in which this issue/RFE has been resolved.
Fixed : Release in which this issue/RFE has been fixed. The release containing this fix may be available for download as an Early Access Release or a General Availability Release.

To download the current JDK release, click here.
JDK 6 JDK 7
6u10Fixed 7 b25Fixed
Description
java.awt.dnd.DropTarget.<init> takes about 5.5% of Notepad startup time according to Netbeans profiler.

Most of the time is spent inside SystemFlavorMap.getDefaultFlavorMap().

However, it seems that initializing default flavor map is not really necessary on startup and could be postponed. It is only used to initialize private transient variable and this initialization can be delayed until after startup (e.g. to the time of first use). See suggested fix.

Preliminary test shows noticeable performance inprovement for startup3 benchmark.
Especially on tiny swing applications:

============================================================================
logs/mybuild
  Benchmark         Samples        Mean     Stdev             Geomean Weight
  startup3               25        3.94      0.03
    Framer               25        0.66      0.04
    JEdit                25        3.13      0.09
    LimeWire             25        3.99      0.02
    NetBeans             25       10.03      0.07
    Noop                 25        0.16      0.00
    XFramer              25        0.80      0.05
============================================================================
logs/mybuild.dd
  Benchmark         Samples        Mean     Stdev   %Diff    P   Significant
  startup3               25        3.75      0.05    4.85 0.000          Yes
    Framer               25        0.58      0.00   11.84 0.000          Yes
    JEdit                25        2.97      0.08    5.07 0.000          Yes
    LimeWire             25        3.85      0.04    3.41 0.000          Yes
    NetBeans             25        9.68      0.29    3.47 0.000          Yes
    Noop                 25        0.16      0.00    1.49 0.034            *
    XFramer              25        0.64      0.00   20.04 0.000          Yes
============================================================================

Comments
EVALUATION after evaluatio I've came to the followin way to change the code to postpone the initialization: 1. I've changed DropTarget to initialize flavorMap field in ctor, since otherwise we could initialize it (as inline initializer) and then rewrite it in ctor. 2. I've decided to not postpone initialization of flavorMap field (as Igor suggested) since getDefaultFlavorMap() uses context class loader of the current thread, thus calling the same method from another thread may have different result. So, theoretically, such change may cause regression if someone uses this particular aspect of the current behavior. Instead of postponing initialization of flavorMap, I've decided to make SystemFlavorMap lazily initialized. For this reason I've extracted all code we had in ctor of this class to new method initSystemFlaforMap(). And since it initializes two fields: flavorToNative and nativeToFlavor, I've changed code to not access these fields directly, but use accessors instead and these accessors call initSystemFlavorMap() if needed.
22-11-2007

EVALUATION Need to find all the places in DnD code like the described one. The fix should be also portable back to 6u? releases.
17-09-2007

SUGGESTED FIX *** DropTarget.java Tue Sep 4 21:37:42 2007 --- DropTarget.java.fix Tue Sep 11 16:07:39 2007 *************** *** 460,466 **** * @return the FlavorMap for this DropTarget */ ! public FlavorMap getFlavorMap() { return flavorMap; } /** * Sets the <code>FlavorMap</code> associated --- 460,470 ---- * @return the FlavorMap for this DropTarget */ ! public FlavorMap getFlavorMap() { ! if (flavorMap == null) ! flavorMap = SystemFlavorMap.getDefaultFlavorMap(); ! return flavorMap; ! } /** * Sets the <code>FlavorMap</code> associated *************** *** 851,855 **** * The FlavorMap */ ! private transient FlavorMap flavorMap = SystemFlavorMap.getDefaultFlavorMap(); } --- 855,859 ---- * The FlavorMap */ ! private transient FlavorMap flavorMap; }
11-09-2007