JDK-7181199 : [macosx] Startup is much slower in headless mode for apps using Fonts
  • Type: Bug
  • Component: client-libs
  • Sub-Component: 2d
  • Affected Version: 7
  • Priority: P3
  • Status: Closed
  • Resolution: Fixed
  • OS: os_x
  • CPU: x86
  • Submitted: 2012-07-02
  • Updated: 2013-08-09
  • Resolved: 2012-09-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.
7u40 b08Fixed 8Fixed
A simple test case which creates a Font takes much longer (roughly 2 seconds) to startup in headless mode than in headful mode.

The test case:

public class HeadlessFont {
    public static void main(String[] args) {
        Font font = new Font("Arial", Font.PLAIN, 32);
        System.out.println("font is: " + font);

In headless mode, I observe that Activity Monitor shows the fontd process taking the most CPU%, and this activity continues for several seconds after the java process has exited.  Disk activity also spikes, again continuing for several seconds longer than the java process.

This slowdown with headless was not present in JDK6, in fact headless mode started up faster (1.7s in headless vs 2.35s with the above test case on 6u32).

This caused a >300%/4-second slowdown in startup when we moved our JavaFX testing from 6u26 to 7u4 - JavaFX bug http://javafx-jira.kenai.com/browse/PERF-319.


SUGGESTED FIX http://cr.openjdk.java.net/~bae/7181199/7u10/webrev.00/

EVALUATION The observed difference in the consumed time is caused by SunFontManager::loadFonts(): in case of headless, it takes much more time to complete. In fact all this time is spent in registerFontsOnPath() (about 4000ms in headless mode instead of 0ms in normal mode). This method takes significant time in headless mode, just because it needs to handle font path "/Library/Fonts" which was returned by getPlatformFontPath(); whereas in case of normal mode, the returned font path is empty. The method getPlatformFontPath() delegates actual work to getFontDirs() which is overloaded in CFontManager. In case of CFontManager, this delegate checks whether default toolkit is an instance of LWCToolkit, and returns empty path in that case. Otherwise, it returns "/Library/Fonts" path, in assumption that X11 toolkit is used. Obviously, this check does not work in case of HeadlessToolkit, where the underlying toolkit instance needs to be checked.

EVALUATION Its not clear why this Apple native code is running so slowly or what alternatives we have.