Я пытаюсь создать простое, легкое и отзывчивое приложение с использованием Java Swing. Однако, когда он запускается, перед окном (JFrame) появляется заметная задержка ( > 500 мс).
Я отследил его до конструктора класса 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), вышеуказанная проблема означает, что перед тем, как окно станет видимым, почти целая секунда задержки. Должен ли я использовать другой язык или графический интерфейс для получения производительности, которую я буду после?
Изменить. Если я добавлю Thread.sleep(10000) в качестве первой строки run(), результаты не изменяются (они появляются только через 10 секунд). Это говорит о том, что проблема не вызвана каким-то асинхронным кодом запуска, а вызвана непосредственно вызовом конструктора.
Изменить 2: реализовано, что профилировщик NetBeans может прорисовываться внутри классов JRE и обнаружил, что большую часть времени тратится на инициализацию объекта sun.java2d.d3d.D3DGraphicsDevice (для объекта Window нужны экраны и вставки), который является частью "Direct3D Accelerated Rendering Pipeline для платформ Microsoft Windows, включен по умолчанию", представленный в Java 6u10. Его можно отключить, передав в JVM свойство "-Dsun.java2d.d3d = false", что уменьшает время запуска примерно на 3/4, но я еще не уверен, что мне это понадобится (D3D) или если есть другой способ заставить его загружаться быстрее. Вот вывод, если я поставлю этот параметр в командной строке:
0 for first Window
47 for first JFrame.
0 for second JFrame.
Я вернусь и очищу это сообщение после того, как я углубился позже.