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

GetDC called way too many times - causes bad performance.

XMLWordPrintable

    • 2d
    • b25
    • x86
    • windows_7

        FULL PRODUCT VERSION :
        java version "1.7.0_02"
        Java(TM) SE Runtime Environment (build 1.7.0_02-b13)
        Java HotSpot(TM) 64-Bit Server VM (build 22.0-b10, mixed mode)

        ADDITIONAL OS VERSION INFORMATION :
        Microsoft Windows [Version 6.1.7601]

        EXTRA RELEVANT SYSTEM CONFIGURATION :
        Any PC with at least 8 CPU cores.

        A DESCRIPTION OF THE PROBLEM :
        After some investigation of why multiple instances of certain java apps won't startup in a timely manor, we tracked down the fact that \jdk\src\windows\native\sun\font\fontpath.c make calls the Windows API GetDC(NULL) hundreds of times in service of the Java_sun_awt_Win32FontManager_populateFontFileNameMap0(...) function. We isolated and reproduced the same performance issue in a standalone program based on \jdk\src\windows\native\sun\font\fontpath.c and believe that a) the calls to GetDC(NULL) leak handles, and b) calling GetDC once, saving the handle and passing the saved handle into all EnumFontFamiliesExW() calls restores performance.

        REGRESSION. Last worked in version 1.4.2

        STEPS TO FOLLOW TO REPRODUCE THE PROBLEM :
        1. Take code given below and create a file named TrueTypeJokerman.java
        2. compiler (using javac.exe) into TrueTypeJokerman.class
        3. from a dos command prompt, run the following command:

        for /l %i in (1,1,16) do start /B cmd /C "C:\Program Files\Java\jdk1.7.0_02\jre\bin\java.exe" TrueTypeJokerman

        and notice how long it takes for the apps windows to appear _and_ that until they do, the system seems frozen.

        EXPECTED VERSUS ACTUAL BEHAVIOR :
        EXPECTED -
        expect application windows to appear quickly...within just a second or two.
        ACTUAL -
        It takes about 45 seconds for all 16 app windows to appear. During this time, the system is frozen and you can't even click to bring task manager up.

        If I try to start 32 process instances, it takes a whopping 195 seconds before the app windows appears.

        REPRODUCIBILITY :
        This bug can be reproduced always.

        ---------- BEGIN SOURCE ----------
        import java.awt.Font;
        import java.awt.GraphicsEnvironment;

        import javax.swing.JFrame;
        import javax.swing.JLabel;

        public class TrueTypeJokerman extends JFrame {

          private String textMessage = "Java Internationalization";

          public TrueTypeJokerman() {
            GraphicsEnvironment ge = GraphicsEnvironment.getLocalGraphicsEnvironment();
            ge.getAllFonts();

            Font font = new Font("Jokerman", Font.PLAIN, 35);
            JLabel textLabel = new JLabel(textMessage);
            textLabel.setFont(font);

            getContentPane().add(textLabel);
            setVisible(true);
          }

          public static void main(String[] args) {
            JFrame frame = new TrueTypeJokerman();
            frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
            frame.pack();
            frame.setVisible(true);
          }
        }
        ---------- END SOURCE ----------

              prr Philip Race
              webbuggrp Webbug Group
              Votes:
              0 Vote for this issue
              Watchers:
              6 Start watching this issue

                Created:
                Updated:
                Resolved:
                Imported:
                Indexed: