Новый ускоритель HotSpot для Java-приложений готов. Что это такое и оправдывает ли он надежды программистов?
Места в программе, снижающие общую производительность, зарубежные программисты называют HotSpot, что можно перевести на русский язык как «горячее пятно». А еще слово «горячий» употребляется при упоминании какой-нибудь новинки. Что с той, что с этой точки зрения новый ускоритель для Java-приложений HotSpot компании Sun Microsystems — «горячая» штучка. Java HotSpot настроен на работу с технологией Java 2, поэтому, если вы решите попробовать этот ускоритель, позаботьтесь о том, чтобы на вашем компьютере был установлен JDK 1.2.x.
Три составляющих технологии — адаптивный компилятор, синхронизация потоков, улучшенный сборщик мусора — нашли реализацию внутри ускорителя HotSpot. Адаптивный компилятор начинает работать после запуска стандартного интерпретатора байт-кода; он анализирует выполнение приложения и обнаруживает «узкие» участки — «горячие пятна». Такие места программы компилируются, при этом ее наибольшая часть остается нетронутой. Компиляция, в свою очередь, также представляет собой многоступенчатый процесс. Например, адаптивному компилятору нужно решить, какую оптимизационную технологию следует использовать в том или ином случае. По задумке авторов HotSpot подобного рода адаптация позволит избежать работы компилятора наугад.
Усовершенствованный сборщик мусора работает способом, отличным от принятого в обычной виртуальной машине Java. Вдобавок сборщик мусора HotSpot может работать в специальном инкрементальном режиме, повышая плавность выполнения приложений. А это как раз то место технологии Java, на которое наиболее часто жалуются потребители.
С технической точки зрения Java HotSpot является архивом, в котором лежат три файла:
- jvm.dll — библиотечный файл ускорителя (предположительно новая виртуальная машина Java);
- jvm_g.dll — отладочный вариант библиотечного файла ускорителя;
- Xusage.txt — справочник по расширенным опциям запуска виртуальной машины.
Инсталляция HotSpot происходит в два этапа. Сначала распаковывается дистрибутивный архив, затем полученные файлы переносятся в специальный каталог hotspot среды исполнения Java (JRE). Здесь возможны два варианта. Если на вашем компьютере установлен JDK 1.2, то следует найти место в его главном каталоге, где установлена среда выполнения JRE. Обычно это каталог с аналогичным именем. Внутри него находится подкаталог bin, в котором и следует создать новый каталог hotspot и куда затем будут скопированы файлы jvm.dll, jvm_g.dll и Xusage.txt. К примеру, на компьютере автора полный путь к каталогу ускорителя будет следующим:
D:SunJDKjreinhotspot
Если же у вас на компьютере инсталлирована только среда выполнения Java, то путь к каталогу ускорителя, скорее всего, будет таким:
C:Program FilesJavaSoftJRE1.2binhotspot
Проверить, как прошла инсталляция, легко — нужно набрать команду
java -version
Если все прошло как по маслу, то виртуальная машина Java даст вам «отмашку» в виде информационного сообщения, говорящего об успешном подключении HotSpot:
java version «1.2.1» HotSpot VM (1.0fcs, mixed mode, build E)
Если была допущена ошибка, то отзовется не HotSpot, а обычная «классическая» виртуальная машина из JDK:
java version «1.2.1» Classic VM (build JDK-1.2.1-A, native threads)
Обычно подобные проблемы возникают при неправильном задании каталога установки.
По завершении данных операций ускоритель Java HotSpot будет запускаться каждый раз, как вы наберете «волшебное слово» java в командной строке. Чтобы отключить использование HotSpot, нужно набрать специальный ключ -classic. Эта опция обязательно должна быть первой после команды java. Точно так же следует поступать и при запуске аплетов через утилиту appletviewer. В целом же опции командной строки Java остаются теми же, что и были до инсталляции HotSpot. Расширенные опции командной строки показаны в таблице.
Итак, казалось бы, все ясно — устанавливай и наслаждайся скоростью. И все-таки интересно было проверить Java HotSpot в деле. Перепробовав почти все имеющиеся у автора приложения Java, он пришел к неутешительной мысли, что только половина из них работают с HotSpot быстрее. Остальные же либо остаются на старом уровне производительности, либо вовсе начинают тормозить. Это квазитестирование проводилось на компьютере с процессором AMD K6-200 и оперативной памятью размером 64 Мбайт. Операционная система Microsoft Windows 98.
Рис.1. После запуска того же самого примера с включенным ускорителем Java HotSpot стало очевидно, что скорость отрисовки упала, но работа сборщика мусора улучшилась. Это хорошо видно на рис. 2 |
Рассмотрим работу стандартного демонстрационного приложения Java2Demo, расположенного в каталоге demojfcJava2D. Оно служит для наглядного показа возможностей программного интерфейса рисования Java2D. Примера лучше не придумать: интенсивная загрузка процессора и постоянная перерисовка окна. Так вот в ходе субъективного замера (с помощью обычного секундомера) удалось выяснить, что обычная виртуальная машина с JIT-компилятором Symantec работает примерно на 19-20% (!) быстрее виртуальной машины с ускорителем HotSpot. Единственное преимущество последнего — несомненная плавность движения графических объектов на экране. Это, по всей видимости, достигается за счет умной сборки мусора. Данное утверждение иллюстрируется графиками загрузки оперативной памяти, отображаемыми все тем же примером Java2Demo. При запуске с ключом командной строки -classic сборщик мусора дожидается момента, когда вся память израсходована, и одним махом очищает ее, вызывая заметную на глаз задержку. Это иллюстрирует график в виде «крокодиловой спины», показанный на рис. 1.
Конечно, графическая задача трудна. Проверим HotSpot на собственном маленьком тесте, занимающемся последовательным размещением миллиона чисел с плавающей точкой на стеке с последующим их снятием и суммированием:
import java.util.*; public class Sample { public Sample(int number) { double tmp = 0D; Stack storage = new Stack(); System.out.println(«Prepare...»); try { Thread.currentThread().sleep(5000); } catch (InterruptedException e){}; System.out.println(«Start!»); for(int i = 0 ; i < number ; i++) storage.push(new Double(i)); try { for(;; tmp += ((Double)storage. pop()).doubleValue()) {}; } catch (EmptyStackException e){} finally { System.out.println(tmp);} } public static void main(String[]args) { final Sample s = new Sample (1000000); } }
Рис. 2. Сначала сборщик мусора работает, что называется, «на пределе». Видимо, в этот момент и происходит адаптивная компиляция, когда HotSpot пытается разобраться с запущенным кодом. Спустя некоторое время загрузка оперативной памяти резко падает, а это означает, что компилятор «понял», как выдерживать оптимальный режим выполнения задачи |
Данное приложение создает стек, дает команду приготовиться, затем выжидает 5 с и запускает процесс размещения и суммирования данных. По завершении работы результат выводится на экран монитора. На этой задаче HotSpot проиграл обычной виртуальной машине Java с JIT-компилятором Symantec 10—13% (было произведено несколько замеров секундомером).
Как видите, результат неутешителен. Разумеется, подобные тесты носят приблизительный характер. Нельзя поручиться, что на компьютере с Microsoft Windows NT и другой аппаратной конфигурацией Java HotSpot не обгонит «классическую» виртуальную машину на тех же самых тестах. Тем более что половину наших задач HotSpot все же ускорил.
Остается вопрос: так ли HotSpot горяч, как его преподносит Sun? Трезвый расчет показывает, что попытки ускорить выполнение байт-кода программно не дадут сколько-нибудь значительного прогресса, а скорость все же следует искать там, где она и должна быть, — в Java-процессорах.
Расширенные опции ускорителя Java HotSpot | |
-Xint | Используется только режим интерпретации без компиляции |
-Xbootclasspath:<каталоги и zip/jar-архивы, перечисленные через ;> | Устанавливает путь для поиска классов и ресурсов, подгружаемых раньше библиотечных классов Java |
-Xnoclassgc | Отключает сборку мусора, оставшегося от использования классов |
-Xincgc | Разрешает инкрементальную сборку мусора (понижает скорость примерно на 10%) |
-Xbatch | Отключает фоновую компиляцию длинных методов |
-Xms<размер> | Задает начальный размер «кучи» Java |
-Xmx<размер> | Задает максимальный размер «кучи» Java |
-Xprof | Выводит профилировочные данные |
-X | Выводит сообщение об использовании нестандартных опций |