Первый вызов конструктора JFrame занимает много времени во время запуска приложения Swing (из-за java.awt.Window ())

Я пытаюсь создать простое, легкое и отзывчивое приложение с использованием Java Swing. Однако при запуске появляется заметная задержка (> 500 мс) перед появлением окна (JFrame).

Я отследил это до конструктора класса java.awt.Window, который является предком JFrame.

Как ни странно, конструктор работает медленно только при первом вызове. Если я создаю несколько объектов JFrame, время, потраченное в конструкторе, составляет ~ 600 мс для первого объекта, но обычно измеряется как 0 мс для последующих объектов.

Вот простой пример, который в моей системе показывает эту значительную задержку для первый вызов конструктора, но не второй:

public static void main(String args[]) {
    java.awt.EventQueue.invokeLater(new Runnable() {
        public void run() {
            long start;

            start = System.currentTimeMillis();
            JFrame frame1 = new JFrame();
            System.out.println((System.currentTimeMillis() - start) + " for first JFrame.");

            start = System.currentTimeMillis();
            JFrame frame2 = new JFrame();
            System.out.println((System.currentTimeMillis() - start) + " for second JFrame.");
        }
    });
}

Типичный вывод:

641 for first JFrame.
0 for second JFrame.

Если я добавлю инициализацию этого объекта Window перед объектами JFrame:

java.awt.Window window = new java.awt.Window(null);

Тогда вывод изменится на что-то вроде:

578 for first Window.
47 for first JFrame.
0 for second JFrame.

Когда я попробую то же самое с суперкласс Window, java.awt.Container, конструктор Window по-прежнему является тем, выполнение которого требует много времени (поэтому проблема не выходит за пределы класса Window).

Поскольку конструктор JFrame вызывает конструктор Window вышесказанное, похоже, указывает на то, что первый вызов конструктора Window стоит дорого.

Что происходит при первом вызове конструктора, который занимает так много времени, и могу ли я что-нибудь с этим сделать? Есть ли какое-нибудь простое решение или проблема является фундаментальной для Swing / AWT? Или, возможно, это проблема, специфическая для моей системы / настройки?

Я бы хотел, чтобы мое приложение открывалось так же быстро (или почти так же быстро), как MS Notepad, и, хотя я могу напечатать текст на консоли примерно в любое время Открывается Блокнот (если я помещаю код перед первой инициализацией JFrame), указанная выше проблема означает, что до того, как окно станет видимым, есть почти целая секунда задержки. Придется ли мне использовать другой язык или среду графического интерфейса, чтобы добиться желаемой производительности?


Edit : Если я добавлю Thread.sleep (10000) в качестве первой строки run (), результаты не будут t изменяются (они появляются только через 10 секунд). Это говорит о том, что проблема не вызвана каким-то асинхронным кодом запуска, а вместо этого запускается непосредственно вызовом конструктора.

Редактировать 2 : осознал, что профилировщик NetBeans может профилировать внутри классов JRE, и обнаружил, что большую часть времени тратится на инициализацию объекта sun.java2d.d3d.D3DGraphicsDevice (объекту Window требуются границы экрана и вставки), который является частью «конвейера ускоренного рендеринга Direct3D для платформ Microsoft Windows, включен по умолчанию», представленного в Java 6u10 . Его можно отключить, передав свойство "-Dsun.java2d.d3d = false" в JVM, что сокращает время запуска примерно на 3/4, но я еще не уверен, понадобится ли оно мне (D3D) или если есть другой способ заставить его загружаться быстрее. Вот результат, если я введу этот параметр в командную строку:

0 for first Window
47 for first JFrame.
0 for second JFrame.

Я вернусь и прочищу этот пост после того, как копну глубже позже.

13
задан A Coder 9 August 2011 в 18:39
поделиться