United StatesChange Country, Oracle Worldwide Web Sites Communities I am a... I want to...
JDK-7131153 : GetDC called way too many times - causes bad performance.

Details
Type:
Bug
Submit Date:
2012-01-18
Status:
Resolved
Updated Date:
2014-04-15
Project Name:
JDK
Resolved Date:
2012-02-07
Component:
client-libs
OS:
windows_7
Sub-Component:
2d
CPU:
x86
Priority:
P3
Resolution:
Fixed
Affected Versions:
8
Fixed Versions:

Related Reports
Backport:
Backport:
Backport:
Backport:
Backport:

Sub Tasks

Description
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 ----------

                                    

Comments
SQE has functional test for this bug fix. The results are ok for jdk8 and jdk8u5. So, SQE OK to take the fix into CPU14_02
                                     
2014-01-27
CAP member had reported the same issue and would like back port the fix to 7 update release -

Have a number of users running a GUI application on Windows 7 and been reported fairly slow performance. After working with Microsoft it turns out that Java 7 creates excessive number of GDI DeviceContext objects within FontManager. Further investigation has conclude that the issue has been addressed in Java 8 with this bug.

Have tested the problem with the testcase provided there and it definitely trigger the issue, and trying Java 7 Update 51 this issue still occurs.

Would like backport this fix back into Java 7 stream.
                                     
2013-12-20
2D_Font/SetFontPerformanceTest
                                     
2013-06-28
EVALUATION

I don't know how much of a regression this can be since the code that
introduced this was actually a massive performance *improvement* for startup.
Previously requesting a font triggered opening all the windows font files.
Now it doesn't.
However we clearly want to fix a leak and take any improvements we can get.
On my PC this shaves about 33ms off the JNI call time. Down from 40ms to 7ms.
The overall overhead of the lookup including java code we execute
around it means its probably down from about 250ms to 210ms.
I'm not sure if it can therefore account for everything the bug reporter
sees but its a nice saving and should fix the leakage.
                                     
2012-01-19
EVALUATION

I think someone internal noticed this but I forgot to file a bug about it.
We've looked for DC leaks before and I can only suppose that because this
code path is executed only once that it didn't show up as being a leak due
to already having happened and being in a steady state once we are up and running.
                                     
2012-01-18



Hardware and Software, Engineered to Work Together