4. Про Excelsior JET?
• Полная реализация Java SE
– первый релиз 2000 год
– c 2005 года cертифицирована как Java Compatible
• AOT compiler + Java Runtime
– смешанная компиляция: AOT + JIT
– поддержка нестандартных загрузчиков классов в
AOT режиме (для Eclipse RCP, Tomcat)
• Toolkit
– Startup Optimizer
– Deployment
5.
6. Кто знает про Excelsior JET?
Кто знает про Excelsior JET?
7. Для чего Excelsior JET?
• Ускорение приложений без переписывания
• Защита кода от декомпиляции
• Распространение приложений без
зависимостей в компактном и привычном
для конечного пользователя виде
14. Защита приложений
• Декомпиляция настолько же сложна как для программ,
написанных на C/C++
• На выходе реальный машинный код без символов (невозможно
понять даже структуру приложения)
• Нет 1-1 соответствия между оригинальным байт-кодом и
результирующим машинным кодом
• После оптимизации приложения с использованием открытой
подстановки и других оптимизаций, результирующий код далек
от оригинального
• Есть возможность закриптовать ресурсы и reflection программы
(не видны простым просмотром)
17. Холодный старт vs
теплый
Во второй раз приложение стартует
значительно быстрее, чем в первый
– Загрузка кода и данных приложения с
диска
– Загрузка системных и сторонних
динамических библиотек (dll, so)
18. AOT быстрее?
• Машинный код “толще” Java bytecode
• Загрузка кода с диска занимает
больше времени, чем его начальное
исполнение
19. AOT быстрее!
• Код исполняемый на старте – в начало
«экзешника»
• Можно предзагружать стартовый
сегмент последовательным чтением
22. Пользовательские
загрузчики классов
• Если AOT компилятор знает логику загрузки
определенного загрузчика, он может классы,
загружаемые этим загрузчиком компилировать до
исполнения
• Eclipse RCP
• Tomcat
23. Excelsior JET Global Optimizer
• Глобально оптимизированный
исполняемый файл
– «нужные» классы приложения и Java
платформы оптимизируются совместно
• Оставшиеся классы
– не удаляются
– остается возможность загружать их через
JIT
24. Java Runtime Slim-Down
• Java SE API делится на
компоненты:
– Kernel, XML, SQL, CORBA, AWT/Java2D,
Swing, etc.
• анализатор определяет какие
компоненты “нужны”
– содержат достижимые методы
26. Java Runtime Slim-Down
• Пользователю предоставляются:
– результаты анализа c возможностью
исключить неиспользуемые компоненты
27. Java Runtime Slim-Down
• Исключенные компоненты:
– помещаются на веб-сервер (доступны
приложению)
– загружаются VM по требованию
• Соответствует Java SE
спецификации!
31. Оптимизации
• Виды оптимизаций
–
–
–
–
–
–
–
–
–
–
Протяжка констант
Удаление избыточного кода
Удаление общих подвыражений
Открытая подстановка
Специализация методов
Развертывание циклов
Версионирование циклов
Вынос инвариантов
Удаление хвостовой рекурсии
Девиртуализация вызовов
– Аллокация объектов на стэке и
их взрыв
– Удаление проверок времени
исполнения
– Удаление избыточной
синхронизации
– Оптимальная выборка кода и
свертка шаблонов
– Планировка инструкций
– Оптимальное распределение
регистров
32. Анализ потока данных
• Протяжка констант
• Удаление общих подвыражений
• Оптимальное распределение
регистров.
• И многое другое
33. Java – ООП
• Много методов
• Методы маленькие (get/set)
• Методы по умолчанию
ВИРТУАЛЬНЫЕ
34. Девиртулизация
вызовов
• Предусловие дальнейшей открытой
подстановки (inline)
• Анализ иерархии классов
– метод не перегружается – невиртульный
• Типовый анализ
– new T().foo(); //вызов foo() невиртульный
35. Аллокация объектов
на стэке
• Все Java объекты создаются в динамической
памяти – Java heap (куча)
• Большинство объектов временные
• Хочется их размещать на стэке метода
• Escape анализ (анализ утечек) –
определяет утекает ли объект в
разделяемую память.
36. Глобальный анализ
• Типовый и Escape анализы боятся
вызовов, особенно виртуальных.
• Глобальный анализ – анализирует все
методы программы, в частности
уточняя типовый и escapе анализы.
37. Анализы и оптимизации
• Часто бывают довольно сложными
• Требуют итеративного пересчета
• Глобальный анализ зависит от ВСЕЙ
программы.
38. Анализы и оптимизации
• Часто бывают довольно сложными
• Требуют итеративного пересчета
• Глобальный анализ зависит от ВСЕЙ
программы.
Все ли это может
себе позволить JIT?
40. Горячий код vs теплый
• А что будет, если у приложения нет
ярко выраженного горячего кода?
• Долгий прогрев, результаты прогрева
не используются при дальнейших
стартах приложения
42. Memory Manager
• Не непрерывная структура хипа (блок – 16 КB)
– Позволяет не только брать память, но и
отдавать
• Специализированные аллокаторы
– Маленькие объекты
– Средние объекты
– Большие объекты
– Ключевые объекты (граф объектов умирает
одновременно, в большинстве случаев)
43. GC
• Адаптивная сборка мусора
– GC старается жить в том пространстве свободной памяти,
что есть (maxheap – это только барьер за который нельзя
заходить)
– Может не только потреблять память, но и отдавать, если
память не нужна
– Пытается ужиться с другими процессами запущенными на
машине
– Наблюдает не только за Java кучей, но и за потреблением
памяти в нативном коде
– Можно выставить gc ratio (хинт GC, говорящий сколько
может потратить GC времени в сравнении с самим
приложением)
44. Parallel Concurrent Incremental
Mark Compact GC
• Алгоритм из класса трассирующих.
• Parallel – исполняется на нескольких процессорах во
время остановки мира
• Concurrent – делает часть работы во время исполнения
– foreground (потоки приложения занимаются сборкой мусора)
– background (в фоновом потоке)
• Incremental – не обходит все объекты каждый цикл
• Mark-Compact – решает компактизировать ли кучу
– делает это в «плановом порядке», а не «когда уже приперло»
– не делает перемещение и настроку части кучи каждый раз
– фрагментация кучи < 5% (чаще всего)
•
45. JIT + AOT модель исполнения
• Reflective shield: незарезолванные ссылки во время
AOT компиляции превращаются в специальный код
(рефлективные стабы), который может резолваться
во время исполнения.
• JIT и AOT порождают одни и те же ран-тайм
структуры.
• JIT и AOT имеют общий код
46. Планы
• Java 7 и Linux AMD64 (декабрь 2013)
• Mac OSX (май 2014)
• Java 8, Linux ARM, compact profiles
• iOS
• Android