Недавно мы писали о том, на какие ухищрения пошла Alibaba, чтобы сделать себе жизнь с OpenJDK более приемлемой. Там были комментарии вроде «оказывается, пока мы тут страдаем с обычной джавой, китайцы уже сделали себе свою особенную». Alibaba, конечно, впечатляет — но и в России есть свои фундаментальные проекты, где тоже делают «особенную джаву».


В Новосибирске вот уже 18 лет делают свою собственную JVM, написанную полностью самостоятельно и востребованную далеко за пределами России. Это не просто какой-то форк HotSpot, делающий всё то же самое, но чуть лучше. Excelsior JET — это комплекс решений, позволяющих делать совершенно другие вещи в плане AOT-компиляции. «Пфф, AOT есть в GraalVM», — можете сказать вы. Но GraalVM — это всё ещё очень исследовательская штука, а JET — это проверенное годами решение для использования в продакшене.


Это интервью с одними из разработчиков Excelsior JET. Надеюсь, оно окажется особенно интересно всем, кто хочет открыть для себя новые вещи, которые можно делать с Java. Либо людям, которые интересуются жизнью JVM-инженеров и сами хотят в этом поучаствовать.



Осенью я прилетел на одну из новосибирских Java-конференций, мы засели с Иваном Углянским dbg_nsk и Никитой Липским pjBooms (одними из разработчиков JET) и записали вот это интервью. Иван занимается рантаймом JET: GC, загрузка классов, поддержка многопоточности, профилирование, плагин для GDB. Никита — один из инициаторов проекта JET, поучаствовал в исследовании и разработке практически всех компонентов продукта от ядра до продуктовых свойств — OSGi на уровне JVM, Java Runtime Slim Down (Java-модули в JET были уже в 2007 году), два верификатора байткода, поддержка Spring Boot и так далее.




Олег Чирухин: Можете рассказать для несведущих людей про ваш продукт?


Никита Липский: Удивительно, конечно, что мы на рынке 18 лет, и нас не так много знают. Мы делаем необычную JVM. Необычность в ставке на AOT-компиляцию, т.е. мы стараемся заранее скомпилировать Java-байткод в машинный код.


Изначально идея проекта состояла в том, чтобы сделать Java быстрой. Производительность — это то, с чем мы шли на рынок. А когда мы шли, Java еще интерпретировалась, и статическая компиляция в машинный код обещала улучшить производительность Java даже не в разы, а на порядки. Но даже в присутствии JIT, если ты заранее все компилируешь, то не тратишь ресурсы во время исполнения на компиляцию, и, таким образом, ты можешь тратить больше времени и памяти и в итоге получать более оптимизированный код.


Кроме производительности побочный эффект от статической компиляции байткода — это защита Java-приложений от декомпиляции. Потому что после компиляции не остается байткода, остается только машинный. Его гораздо сложнее декомпилировать в исходный код, чем Java-байткод. Фактически невозможно. То есть его можно дизассемблировать, но исходники ты не породишь. А вот из байткода породить Java-исходники с точностью до имен переменных можно легко, для этого есть множество инструментов.


Кроме того, когда-то давно предполагалось, что Java стоит на всех компьютерах, ты распространяешь свои Java-приложения в виде байткода, и они везде исполняются одинаково. Но в реальности всё было не так хорошо, потому что у одного стоит одна Java, у другого — другая. Из-за этого, если ты распространял программу в виде байткода, могли происходить разного рода неожиданности, начиная с того, что пользователь просто не мог запустить твою программу, заканчивая каким-нибудь странным поведением, которое ты не мог проявить у себя. У нашего же продукта всегда было преимущество в том, что ты распространяешь свое Java-приложение просто как нативное приложение. У тебя нет зависимости от рантайма, который стоит (или не стоит) у пользователя.


Иван Углянский: Вообще не нужно требовать, чтобы Java была установлена.


Олег: Остается зависимость на операционную систему, да?


Никита: Верно. Многие критикуют, что если ты компилируешь в нативный код, то у тебя лозунг «Write once — run anywhere» перестает работать. Но это не так. Я на своих докладах периодически об этом рассказываю, что «write once» звучит как «write once», а не «build once». То есть ты можешь собрать на каждую платформу свое Java-приложение, и оно будет работать везде.


Олег: Прям везде-везде?


Никита: Везде, где поддерживается. У нас Java-совместимое решение. Если ты пишешь на Java, то будет работать там, где работает Java. А если используешь скомпилированное нами, то там, где мы это поддерживаем — Windows, Linux, Mac, x86, amd64, ARM32. Но где не поддерживаем, ты все равно можешь использовать обычную Java для своих приложений, то есть переносимость твоих Java-приложений в этом смысле не страдает.


Олег: Есть такие конструкции, которые по-разному выполняются на разных платформах? Куски платформы, которые не до конца реализованы, какие-нибудь стандартные библиотеки.


Иван: Такое бывает, при этом это не JET-специфично. Вы можете посмотреть, например, на реализацию AsynchronousFileChannel в самом JDK, он совсем разный на разных Windows и на Posix, что логично. Некоторые вещи реализованы только на определенных платформах, поддержка SCTP (см. sun.nio.ch.sctp.SctpChannelImpl на Windows) и SDP (см. sun.net.sdp.SdpSupport). В этом тоже нет особого противоречия, но действительно получается, что «Write once, run anywhere» — это не совсем правда.


Если говорить именно про реализацию JVM, то на разных OS разница, конечно, может быть огромной. Чего стоит тот факт, что на OS X в main-треде нужно запускать Cocoa event loop, поэтому запуск там отличается от остальных.


Никита: Тем не менее, снаружи для пользователя оно все выглядит и работает практически одинаково.


Олег: Что насчет перформанса? Он тоже одинаковый на всех платформах?


Никита: Есть разница. Например, линуксовая файловая система работает лучше и шустрее, чем виндовая.


Олег: А портирование между процессорами?


Никита: Это веселое занятие! Вся команда вдруг неожиданно начинает портировать. Развлечение обычно на полгода-год.


Олег: Бывает так, что какой-то кусок кода на другой платформе начинает тормозить сильнее?


Иван: Это может быть из-за того, что мы просто не успели сделать или адаптировать какую-то оптимизацию. Она хорошо работала на x86, потом мы перешли на AMD64, и просто не успели ее адаптировать. Из-за этого может быть медленнее.


Еще пример по поводу производительности. На ARM слабая модель памяти, там нужно ставить гораздо больше барьеров, чтобы все корректно работало. У нас был AMD64, некоторые места работали, считай, нахаляву, потому что там модель памяти другая. На ARM нужно ставить больше барьеров, а это не бесплатно.


Олег: Давайте поговорим про горячую сейчас тему — «Java на embedded-девайсах».
Допустим, я делаю самолетик, который летает с управлением на Raspberry Pi. Какие типичные проблемы случаются у человека, когда он будет это делать? И чем может помочь JET и вообще AOT-компиляция в этом деле?


Никита: Самолетик на Raspberry Pi — это, конечно, интересная тема. Мы сделали ARM32, и теперь JET есть на Raspberry Pi. У нас есть энное количество заказчиков на embedded, но их не так много, чтобы говорить об их «типичных» проблемах. Хотя какие у них есть проблемы с Java, догадаться не сложно.


Иван: Какие проблемы вообще с Java на Raspberry Pi? Проблема есть с потреблением памяти. Если её нужно слишком много, то приложению и JVM тяжело жить на бедном Raspberry Pi. Кроме того, на embedded-девайсах важно иметь быстрый запуск, чтобы приложение не слишком долго там разгонялось. AOT хорошо решает обе эти задачи, поэтому мы работаем над улучшением поддержки embedded-а. Конкретно по поводу Raspberry Pi стоит сказать про Bellsoft, которые сейчас активно занимаются этим c HotSpot. Обычная Java там полноценно присутствует.


Никита: Кроме того, ресурсов на embedded-системах мало, JIT-компилятору там развернуться негде. Соответственно, AOT-компиляция сама по себе разгоняет производительность.


Опять же, embedded-девайсы бывают без включения в сеть, на батарейке. Зачем есть батарейку JIT-компилятору, если можно все заранее собрать?


Олег: Какие у вас есть фичи? Я так понял, что JET — это очень большая сложная система с кучей всего. У вас есть AOT-компиляция, то есть можно скомпилировать экзешник. Что еще? Какие есть интересные составляющие, о которых стоит поговорить?


Иван: У нас есть ряд фич, связанных с производительностью.


Недавно я рассказывал про PGO, нашу сравнительно новую фичу. У нас есть встроенный прямо в JVM профайлер, а также набор оптимизаций, основанный на профиле, который он собирает. После перекомпиляции с учетом профиля мы зачастую получаем серьезный прирост производительности. Дело в том, что к нашим мощным статическим анализам и оптимизациям добавляется информация об исполнении. Это такой немного гибридный подход — взять лучшее от JIT и AOT-компиляции.


Есть у нас две замечательные фичи по еще большему ускорению запуска. Первая — когда смотришь на то, в каком порядке страницы памяти протыкиваются изначально, просто мониторишь это и соответствующим образом перелинковываешь экзешник.


Никита: Второй — когда запускаешь экзешник, понимаешь, какие куски памяти подтягиваются, и потом вместо того, чтобы подтягивать их в каком попало порядке, подтягиваешь сразу нужный кусок. Тоже сильно разгоняет запуск.


Иван: Это отдельные продуктовые фичи.


Никита: Первая называется Startup Optimizer, а вторая — Startup Accelerator. Фичи работают по-разному. Чтобы использовать первую, тебе нужно запустить приложение до компиляции, оно запомнит, в каком порядке у тебя исполнялся код. Потом в нужном порядке этот код залинкует. А вторая — это запуск твоего приложения после компиляции, тогда уже мы знаем, что и куда легло, и после этого мы на запуске протыкиваем всё в нужном порядке.


Кроме фич, связанных с производительностью, есть ряд продуктовых фич, делающих JET удобнее для использования.


Например, мы умеем паковать, скажем, виндовые дистрибутивы. Раз — и получил виндовый инсталлятор. Можешь распространять Java приложения как настоящие нативные приложения. Есть много чего еще. Например, есть такая стандартная проблема с AOT-компиляторами и Java, когда приложение использует свои собственные загрузчики классов. Если у тебя свой собственный загрузчик классов, непонятно, какие классы мы будем AOT-компилировать? Потому что там логика резолва между классами может быть какая угодно. Соответственно, ни один Java AOT-компилятор, кроме нашего, не работает с нестандартными загрузчиками классов. У нас есть специальная поддержка в AOT для некоторых классов приложений, где мы знаем, как работают их кастомные загрузчики, как разрешаются ссылки между классами. К примеру, у нас есть поддержка Eclipse RCP и есть клиенты, которые пишут десктоп-приложения на Eclipse RCP и компилируют нами. Есть поддержка Tomcat, там тоже используются кастомные загрузчики. Tomcat-приложения можешь спокойно нами компилировать. Также у нас недавно вышла версия JET с поддержкой Spring Boot из коробки.


Олег: Какой сервер там «внизу»?


Никита: Какой хочешь. Какой Spring Boot поддерживает, с таким и будет работать. Tomcat, Undertow, Jetty, Webflux.


Иван: Тут нужно упомянуть, что для Jetty у нас нет поддержки его кастомных класслоадеров.


Никита: У Jetty, как отдельно стоящего веб-сервера, есть кастомный класслоадер. Но есть такая вещь, как Jetty Embedded, которая может работать без кастомных загрузчиков. Jetty Embedded спокойно работает на Excelsior JET. Внутри Spring Boot Jetty будет работать в следующей версии, как и любые другие серваки, поддерживаемые Spring Boot.



Олег: По сути, интерфейс общения пользователя с JET — это javac и Java или что-то другое?


Иван: Нет. Для пользователя у нас есть несколько вариантов использования JET. Во-первых, это GUI, в котором пользователь протыкивает все фичи, после этого нажимает кнопку и у него приложение компилируется. Когда хочет сделать какой-нибудь инсталлятор, чтобы пользователь мог поставить приложение, он еще раз протыкивает кнопки. Но такой подход немного устарел (GUI разрабатывали еще в 2003 году), поэтому сейчас у нас Никита занимается разработкой и развитием плагинов для Maven и Gradle, которые гораздо удобнее и привычнее для современных пользователей.


Никита: Подставляешь семь строчек в pom.xml или build.gradle, говоришь mvn jet:build, и у тебя палка колбасы на выходе.


Олег: А сейчас же все очень любят Docker и Kubernetes, можно собрать для них?


Никита: Docker — это следующая тема. У нас есть такой параметр — packaging в Maven/Gradle плагинах. Я могу добавить packaging-приложения для Докера.


Иван: Это еще work in progress. Но в целом, мы пробовали JET-скомпилированные приложения запускать на Docker.


Никита: Работает. Без Java. Голый Linux, засовываешь туда JET-скомпилированное приложение, и оно стартует.


Олег: А с packaging-ом докера что на выходе будет получаться? Контейнер или экзешник руками впихивать в Docker-файле?


Никита: Сейчас просто пишешь JET-специфичный Docker-файл — это три строчки. Далее все работает через штатные Docker-инструменты.


Я сейчас играюсь с микросервисами. Компилирую их JET-ом, запускаю, они друг друга обнаруживают, общаются. Со стороны JVM ничего для этого делать не пришлось.


Олег: Сейчас всякие клаудные провайдеры запустили штуки типа Amazon Lambda, Google Cloud Functions, там можно это применять?


Никита: Я думаю, что нам нужно идти к провайдерам всех этих штук и говорить, что если вы будете нас использовать, то все ваши лямбды будут работать быстрее. Но это еще пока только идея.


Олег: Так они же действительно будут работать быстрее!


Никита: Да, скорее всего, в этом направлении надо будет еще поработать.


Олег: Я тут вижу проблему во времени компиляции лямбды. Какое у вас время компиляции?


Иван: Оно есть, и это проблема, о которой не задумываются пользователи обычных JVM с JIT-ом. Обычно ведь как — запустил приложение, оно работает (пусть сначала медленно из-за компиляции). А здесь появляется отдельный шаг для AOT-компиляции всего приложения. Это может быть чувствительно, поэтому мы работаем над ускорением данного этапа. Например, у нас есть инкрементальная перекомпиляция, когда перекомпилируются только изменившиеся части приложения. Мы называем это смарт-перекомпиляцией. Мы как раз занимались этим в прошлом дев.периоде с Никитой, в паре сидели.


Никита: С Java и со смарт-рекомпиляцией есть определенные проблемы, например циклические зависимости внутри Java приложений — они везде и всюду.


Иван: Там есть много проблем довольно неочевидных, пока не задумываешься об этой задаче. Если у тебя есть статический AOT-компилятор, который делает разные глобальные оптимизации, то не так-то просто вычислить, что конкретно надо перекомпилировать. Нужно все эти оптимизации помнить. А оптимизации могут быть нетривиальными. Например, ты мог сделать всякие сложные девиртуализации, проинлайнить что-то черт знает куда. Если ты поменял один классик или один JAR, это не значит, что только его надо перекомпилировать и всё. Нет, это всё гораздо более запутанно. Нужно вычислять и помнить все оптимизации, которые компилятор сделал.


Никита: Фактически делать все то же самое, что делает JIT, когда он принимает решение про деоптимизацию, но только в AOT-компиляторе. Только решение будет не про деоптимизацию, а про перекомпиляцию.


Олег: Насчет скорости смарт-компиляции. Если я возьму «Hello, World», скомпилирую его, потом изменю две буквы в слове «Hello»…


Никита: Это быстро компилируется.


Олег: В смысле не минуту?


Никита: Секунды.


Иван: Но это еще зависит от того, включаем ли мы в экзешник платформенные классы.


Олег: А что, можно и без этого?


Никита: Да, по умолчанию у нас платформа пилится на несколько DLL. Мы реализовали Jigsaw в самом начале :-) То есть мы попилили Java SE классы на компоненты очень давно, ещё в 90-каком-то-там году.


Иван: Смысл в том, что наш рантайм плюс платформенные классы — они все предкомпилированы нами, и да — разделены на DLL. Когда ты запускаешь скомпилированное JET-ом приложение, то рантайм и вся платформа в виде этих DLL и представлена. То есть в результате это выглядит так: берешь «Hello, world», компилируешь, у тебя компилируется реально один класс. Это происходит за несколько секунд.


Никита: За 4 секунды, если в глобале; за пару секунд, если не в глобале. «Глобал» — это когда ты влинковываешь: все платформенные классы, скомпилированные в нативный код — в один большой экзешник.


Олег: А можно сделать какой-нибудь hot reload?


Никита: Нет.


Олег: Нет? Печаль. Но можно было бы сгенерировать одну DLL, снова её прилинковать и потом…


Никита: Так как у нас есть JIT (кстати, да, у нас есть и JIT тоже!), то ты, конечно же, можешь куски кода загружать, выгружать, обратно загружать. Например, весь код, который работает через наш JIT, в том же OSGI, — его можно перезагружать, если хочешь. Но вот hot reload, который есть в HotSpot, когда ты в отладчике сидишь, и на лету меняешь код, — у нас нет. Это сделать невозможно без потери производительности.


Олег: На этапе разработки производительность не так важна.


Никита: На этапе разработки ты используешь HotSpot, и тебе больше ничего не надо. Мы совместимое с Java-спецификацией решение. Если ты используешь HotSpot и используешь hot reload в отладке, все отлично. Отладил, компилируешь JET, и все работает как на HotSpot. Должно быть так. Обычно так. Если нет, пишешь в саппорт, мы разбираемся.


Олег: А что с отладкой в JET? JVM TI? Насколько все поддерживается?


Иван: Одна из основных ценностей использования JET — это безопасность. Пользовательский код не будет никому доступен. Потому что всё скомпилировано в натив. С этим есть некоторые противоречия, поддерживать ли нам JVM TI? Если мы поддерживаем, то это значит, что любой прокаченный разработчик, который знает, как работает JVM TI, очень быстро сможет получать доступ к чему угодно. Мы JVM TI сейчас не поддерживаем.


Никита: Это опциональная вещь по спецификации. Она может поддерживаться реализаторами платформы, может не поддерживаться.


Иван: Тут много причин. Она опциональная и нарушает безопасность, значит, пользователи нам «спасибо» не скажут. И она внутри очень HotSpot-специфична. Не так давно наши ребята в качестве экспериментального проекта поддерживали JVM TI, они дошли до какого-то этапа, но все время сталкивались с тем, что она очень заточена под HotSpot. В принципе это возможно, но какая бизнес-задача этим решится?


Никита: После того как у тебя заработало на HotSpot, но не заработало на джете — это не твоя проблема. Это наша проблема.


Олег: Понял. А какие-нибудь есть у вас дополнительные фичи, которых
нет в HotSpot, но есть у вас, и они требуют прямого контроля? Которые хотелось бы поотлаживать, поразбираться в них.


Никита: Ровно одна фича. У нас есть официальное расширение платформы под названием Windows Services, то есть ты можешь компилировать Java-приложения в виде настоящих сервисов Windows, которые будут мониториться через стандартные Windows-инструменты для сервисов Windows и так далее. В этом случае ты должен подцепить наш собственный JAR, чтобы скомпилировать такие приложения.


Олег: Это не самая великая проблема.


Никита: Интерфейс очень простой у этих сервисов. А для отладки ты используешь способы запуска своего же приложения не как Windows Service, а через main. Какая-то специфическая для сервиса отладка, не знаю, нужна ли она.



Олег: Допустим, новый разработчик, который раньше работал на HotSpot, хочет разработать что-то с использованием JET, нужно ли ему чему-то научиться, что-то понять вообще о жизни или о JET?


Иван: Ему нужно семь строчек скопировать в pom.xml, если используется Maven, потом запустить jet:build, и если JET стоит на машине, то Java-приложение скомпилируется в экзешник. По идее это просто, ты ничего особенного не делаешь, просто берешь, получаешь экзешник, и всё.


Никита: Либо ты знаешь командную строку, с которой запускается твое приложение, то засовываешь эту командную строку в наш GUI, она разберется. Ты даёшь команду build, получаешь экзешник, всё.


Иван: Это очень просто, ничего нового придумывать не нужно. Как хотспотовский AOT работает, ты сам показывал на докладе, что нужно список всех методов получить в файлик, погрепать его, трансформировать — ничего такого у нас делать не нужно. Просто берешь свою строку запуска на HotSpot, вставляешь ее в специальный GUI, либо в pom.xml добавляешь небольшой кусочек, и, ура, у тебя через какое-то время (потому что это все-таки AOT-компиляция) получается exe-файл, который можно запускать.


Олег: Нужно ли учиться работать с GC?


Никита: Да, GC у нас свой, тюнить его надо по-другому, не как в HotSpot. Публичных ручек у нас очень мало.


Олег: Есть ручка «сделать хорошо» или «не сделать»?


Иван: Есть такая ручка. Есть ручка «выставить Xmx», есть ручка «выставить количество воркеров»… Много ручек, но зачем вам про них знать? Если у вас что-то случится неожиданное — пишите.


Конечно, у нас есть много чего для настройки GC. Можем тюнить молодое поколение, можем частоту прихода GC. Все это тюнится, но это не общепринятые опции. Мы понимаем, что люди знают -Xmx и указывают ее, поэтому мы ее парсим. Есть еще несколько общепринятых опций, которые работают и с JET, но в целом все свое.


Никита: У нас есть еще публичная опция, позволяющая выставить, сколько ты разрешаешь GC тратить времени своего приложения.


Олег: В процентах?


Никита: В десятых процента. Мы поняли, что проценты — это многовато, грубовато.


Иван: Если ты проценты тратишь на GC, у тебя что-то не так.


Олег: А вот все эти люди из энтерпрайзов, которые всё, что делают в рабочее время — открывают распечатку работы GC с графиком и медитируют. У вас можно медитировать?


Никита: У нас есть специальные люди внутри компании, которые медитируют.


Иван: У нас свой формат лога, поэтому люди вряд ли по нему смогут что-то понять. Хотя, мало ли? Если будут долго на него смотреть, может, и смогут понять. Там всё написано. Но, скорее всего, лучше прислать нам, и мы помедитируем.


Олег: Но естественно, вы сделаете это за деньги, а самостоятельно можно смотреть на халяву.


Никита: Если ты наш клиент, то у тебя есть саппорт, и мы это делаем, конечно же, в рамках саппорта.


Иван: Но если у тебя есть какая-то очевидная проблема, мы даже без саппорта можем сказать.


Олег: Если это баг какой-то?


Никита: Если баг, то, конечно, принимаем от всех и всегда. Это не так что «пока не купишь, мы не будем исправлять баг». Если баг, то мы исправляем. Вообще, пользователи любят наш саппорт. Обычно говорят, что он очень качественный, и что они нигде ничего подобного не видели. Возможно дело в том, что мы сами сидим в саппорте, по очереди ротируемся.


Олег: Сами — это кто?


Никита: Разработчики, JVM-инженеры.


Олег: С какой периодичностью?


Никита: Периодичность бывает разная. Обычно по две недели сидим по очереди. Но если ты обязан сделать мегафичу за определённое количество дней, то у тебя в этот момент появляется иммунитет от саппорта, чтобы можно было сосредоточиться на этой задаче.


Иван: По идее все должны делать это по очереди. Но иногда кто-то героически берет вторую дозу и саппортит месяц или больше, а не две недели. Лично я люблю саппортить, но если слишком долго это делаешь, то немножко забываешь, чем занимаешься в жизни, потому что начинаешь только на письма отвечать. А ты все-таки хочешь колбасить JVM. Поэтому через какое-то время нужно возвращаться.


Олег: А у вас иерархия, сколько уровней менеджмента? 20 или больше?


Никита: Ты что, нас всего 10 человек в команде.


Иван: 15 вместе со студентами.


Олег: Я про то, что начальство в этом участвует или просто взирает?


Никита: Про начальство. Конечно, есть главный человек, и есть много локальных руководителей.


Олег: У каждого человека своя область?


Никита: Человек, который берет на себя какую-то большую задачу и руководит ей. Это тоже ротируется. Ты можешь один раз взять большую задачу и руководить, а в следующий раз уже тобой будут руководить.


Иван: В общем, у нас нет большой иерархии. У нас есть один уровень начальства. А по поводу взирать сверху — абсолютно нет. Иногда наше начальство героически берет на себя саппорт, если близится релиз.


Никита: Начальство — один человек, его зовут Виталий Михеев.


Олег: Его где-нибудь можно видеть? На конференциях или еще где-то?


Никита: Вообще мои выступления на конференциях начались с того, что к нам в Новосибирск приехал питерский Java Day, его организовывал Белокрылов из Oracle, который сейчас в Bellsoft. Он спросил, хотим ли мы выступить, и мы тогда выступили вместе с Виталием. Потом я ему предлагал дальше вместе выступать, но он решил, что больше не хочет.


Олег: А что за доклад?


Никита: «История одной JVM в картинках».


Иван: Я помню этот доклад, я тогда был либо стажером, либо только-только перестал им быть. И я до сих считаю, что это один из лучших докладов, которые я видел.


Никита: Возможно, это был «эффект премьеры», когда ты впервые в жизни выступаешь, энергией давишь хорошо.


Олег: А про что вы рассказывали?


Никита: Рассказывали вдвоем про JET от начала до конца в течение 20 минут.


Олег: На двоих всего 20 минут? Обычно, когда несколько человек, время на доклад только увеличивается.


Никита: Мы очень бодренько и живенько рассказали все ключевые темы.


Олег: Ваня, повлияло ли это на твое решение, что делать дальше, работать ли в компании?


Иван: Вполне может быть!


Олег: Просто обычно люди спрашивают, зачем ходить на конференции, на доклады, зачем что-то слушать, если можно погуглить.


Никита: Конечно, на мой взгляд, на конференции ходить очень полезно. Когда у тебя живой контакт, непосредственное участие, — это совсем не то, что в ютюбе посмотреть. Важно, что ты непосредственно, а не виртуально участвуешь. Ты соприкасаешься с первоисточником. Разница примерно такая же, как посетить живой концерт или послушать его в записи. Даже, наверное, большая, потому что ну сколько ты можешь пообщаться со своим любимым исполнителем после концерта? А на конференции можно найти нужного тебе докладчика и все, что надо, у него выспросить — проблем нет.


Иван: Кстати, по поводу решения «остаться в компании», это отдельная история. У нас довольно уникальная система набора сотрудников/стажеров. Мы берем стажеров на 2-3 курсе, обычно с мехмата или с физфака. Стажеры очень глубоко погружаются в тему, кураторы помогают им разобраться в различных механизмах VM, деталях реализации и т.д. — это многого стоит.


Через какое-то время начинают давать боевые задачи, настоящий код в продакшн писать. Ты вносишь изменения в JVM, проходишь ревью, тесты, бенчи — проверяешь, что они не просели. Коммитишь в первый раз. После этого ты сосредотачиваешься на своем дипломе. Обычно диплом — это тоже крутая часть JVM, экспериментальная, исследовательская. Этим занимаются обычно студенты. Потом ты, возможно, его продуктизируешь — а возможно и нет. Я такого нигде не видел, чтобы так много времени тратилось на стажеров. И я лично сам это очень ценю, потому что я помню, сколько на меня потратили времени. На выходе получается JVM-инженер. Где еще есть такая фабрика про производству JVM-инженеров?


Олег: А вы не боитесь утечки информации от стажеров, они же потом в открытом виде это всё в дипломе опишут?


Никита: Это не проблема, потому что мы боимся утечки за рубеж, а по-русски особо никто не будет читать, — это такая защита, обфускация :-)


Иван: У меня защищался студент в этом году, я был руководителем, и там была такая проблема, что не все хотелось в диплом писать. Мы кое-что приоткрыли из закрытой абсолютно темы, и, например, у нас рецензент спросил, почему мы не рассказываем про определённые вещи. Я ему ответил, что нельзя про это рассказывать, это очень секретно, мы не можем. Это есть, я на ушко скажу вам, но это больше никуда не пойдёт. Так что немножко все-таки этого опасаемся, но в целом в дипломах можно много чего интересного найти.


Олег: А как поискать дипломы, которые с участием Excelsior?


Никита: Приходишь в деканат и просишь прочитать такой-то диплом.


Иван: У нас на сайте есть список удачно защитившихся дипломов, но только названия, без ссылок. А неудачно защитившихся у нас не бывает.


Олег: Они либо умирают, либо защищаются.


Иван: Так и есть! У нас средний балл дипломников 5.0, есть те, кто просто не выходит на диплом.


Олег: В этой подготовке, фабрике JVM-инженеров, расскажите, какие есть этапы становления джедаем? Когда тебе выдают световой меч, когда ты им можешь начинать махать?


Никита: Довольно быстро. Сейчас молодежь больно быстро становятся джедаями, я горжусь ими.


Иван: Кстати, Никита был моим первым куратором, когда я был стажером. По поводу стажировки: сначала ты проходишь отбор: решаешь задачи, приходишь на одно или несколько собеседований. Если все ок, то становишься стажером. Первое время читаешь научные статьи на темы, которые, скорее всего, связаны с твоим будущим дипломом, либо просто около-JVM-тематики на английском, чтобы вобрать контекст. Ты читаешь, по ним пишешь реферат, объясняешь, что там происходит. Его очень жестко ревьюят. Некоторые учёные позавидовали бы такой вычитке и такой подготовке реферата. Получаются полноценные статьи на русском. После этого тебе пора писать код, и тебя потихоньку вводят в суть дела — как все это устроено.


Никита: И на этом наука заканчивается.


Иван: Не обязательно!


Никита: Немного обидно, в начале нулевых мы выпускали статьи, которые брали в ACM-овские журналы.


Иван: Ну мы и сейчас это делаем, в чём проблема?


Никита: Какая последняя наша статья попала в ACM-овский журнал?


Иван: Так в ACM-овский мы просто не пытались! Сейчас мы ведем блог — это то же самое, только люди его ещё и читают. Это же похожая деятельность.


Возвращаясь к теме джедайства, после этого ты первый раз делаешь что-то в продакшн под четким контролем. Нужна небольшая задача, не связанная с твоим будущим дипломом.


Олег: Например, написание комментария.


Иван: Нет. Настоящую функциональность. Студент должен сделать свой первый настоящий вклад, чтобы он остался в продукте. Потом он начинает заниматься дипломом, это какой-то исследовательский проект, который затем превращается в диплом. Потом, по-хорошему, он должен это исследование продуктизировать — это четвертый этап. Это не всегда случается, потому что не любое исследование нужно и можно продуктизировать прямо сейчас. В любом случае, после этих этапов получается новый JVM-инженер.


Олег: А какие самые сложные этапы? На что много времени тратят люди? Есть какая-нибудь или математика, или понимание стандарта, или ещё какая-то глубокая штука? Из чего состоит структура знания?


Иван: Я бы сказал, что довольно тяжело впитать в себя так много контекста. Что отличает нашу стажировку от какой-то другой — ты не можешь просто взять тяп-ляп и сделать задачу в продакшн, перед этим нужно понять, как все устроено, хотя бы часть глобальной картины увидеть, учесть очень много факторов, и вообще, много понимать про мир JVM. Помню, как я учился, и у меня этого понимания изначально не было, конечно. Помню, как у меня появлялись вспышки понимания: «Так вот как это работает!». И потихоньку все совмещалось в общую картинку.


Олег: Эта картинка специфичная для JET?


Никита: Нет, для JVM специфична.


Иван: Какие-то части объясняют тебе, почему JET — это JET. Я помню, что когда-то пришел и спросил у одного из кураторов, почему у нас два компилятора: оптимизирующий и baseline-компилятор. Я не очень понимал, зачем и почему. И это был момент, когда у меня случилась вспышка понимания, как этот JET работает.


Олег: А зачем два компилятора?


Иван: Один оптимизирующий, мощный. Второй не такой оптимизирующий, зато быстрее и надежнее работающий.


Никита: Оптимизирующий может когда-нибудь сломаться, а baseline не должен ломаться никогда.


Иван: Кроме того, baseline мы еще используем в качестве JIT. Да, у нас есть и JIT тоже, он необходим для корректности. Но мы не разгоняем в нем оптимизирующий компилятор, вместо этого используем baseline. Вот такой побочный эффект. Если что-то вдруг пошло не так в оптимизирующем, мы можем во время компиляции в качестве запасного варианта использовать baseline, он точно сработает.


Олег: Вы компилируете какие-нибудь UI-приложения? Там важна скорость запуска.


Никита: Разумеется. Мы долго позиционировали себя именно как десктопное решение. Большинство наших пользователей до сих пор на Windows.


Иван: Но насколько я слышал, отношение меняется в сторону других платформ. Например, те же десктопщики используют Mac.


Олег: А можно на Android компилять?


Никита: Мы изучали этот вопрос. Покомпилять можно, под Android же есть Linux-эмулятор, а Linux мы умеем. То есть компилировать под этот Linux на Android можно. На телефоне или планшете запустить какое-нибудь свинговое приложение. Были успешные эксперименты.


Олег: А без Линукса?


Никита: Скомпилировать дексы? Нет.


Олег: У Android же есть Native SDK. Скомпилировать DLL и подцепить.


Никита: Были неудачные эксперименты, чего-то не взлетело, к сожалению. В Андроиде SO-шки как-то подхачены, работают не так, как в Linux, времени разобраться, какие именно отличия, не было. Но есть идея сделать возможность использовать настоящую Java на Android, не андроидовскую, компилировать ее в SO-шку, и потом этот кусок Java мог бы с Dalvik сопрягаться как обычная нативная динамическая библиотека. Можно тогда 90 процентов своего приложения в эту библиотеку запихать, например, всю бизнес-логику.


Олег: А потом можно было бы еще скомпилировать под iOS и сделать универсальную платформу для запуска всего?


Никита: Да. Начать с Android, потом пойти на iOS. Но инвестиций туда требуется очень много, пока мы туда не идем, к сожалению.


Олег: Учитывая, что вас 15 человек.


Никита: iOS мы хотим уже лет десять. Там нужны большие инвестиции, все никак не можем на это решиться.


Иван: Проблема ограниченности ресурсов есть, к сожалению.


Олег: Расскажите про особенности устройства команды?


Иван: Тут стоит сказать, что есть два мощных лагеря — разработчики компилятора и разработчики рантайма.


Олег: У вас же компилируется нативный код. Компилятор и рантайм не являются одним и тем же?


Никита: Рантайм — это полноценная JVM, в JVM очень много всего есть — треды, рефлексия, синхронизация, сборка мусора, управление памятью, — это здоровые куски, они очень сложные. Они местами гораздо более нетривиальные, чем компилятор. Ту же синхронизацию эффективно реализовать может не каждый компиляторный инженер в нашей команде. А если ты в GC где-то ошибся, то все плохо, так как там отладка не работает. Там отладка никакая невозможна, ты сидишь и медитируешь по ночам, отлаживаешь во сне, что там случилось.


Олег: Видел, что Шипилёв писал, например, всякие визуализации работы Шинанды. И у него была такая отладка, там цветом показывалось, как перемещаются блоки. И вы наверняка можете вставить GDB в нативный код.


Иван: Конечно, мы так и делаем. У рантаймщиков и компиляторщиков немного отличаются подходы к разработке, отладке и т.д. Например, т.к. компиляторы у нас написаны на managed-языках Java/Scala, то и разрабатывать и (чаще всего) отлаживать их можно прям из IDEA, что очень удобно и здорово. В рантайме же у тебя только два союзника — GDB и отладочная печать.


Никита: Но, кстати, можно писать unit-тесты на рантайм, и их тоже можно отлаживать в Идее!


Иван: Угу. Но и в целом немного менталитет отличается при разработке компилятора и рантайма. Я бы сказал, что в рантайме главная сложность в том, насколько много всего может происходить одновременно, это нужно понимать и даже чувствовать. Это такое странное ощущение времени и жизни всей JVM. В компиляторе по-другому, но тоже очень интересно. Мы недавно с Пашей Павловым это обсуждали, и он очень круто сформулировал: в компиляторе сложности другого рода, они возникают из-за «комбинаторного взрыва возможных состояний и ситуаций из-за (зачастую совершенно неочевидной) скрытой сложности мат. модели».


В общем, это два таких очень разных мира, но в сумме составляющих одно целое — собственно, всю JVM.


Олег: Вы с какой части баррикад находитесь?


Иван: Я рантаймщик.


Никита: Я компиляторщик. Но в последнее время я делаю продуктовые фичи. Та же поддержка Spring Boot означает, что нужно практически все компоненты JET немножко потрогать, чтобы всё заработало.


Иван: Если нужно, то мы погружаемся в чужие компоненты и что-то там делаем. Кроме того, есть люди, которые ни с какой стороны баррикад, они полноценные гибриды — полукомпиляторщики и полурантаймщики. Например, мы сейчас делаем новый JIT, и это полноценная работа с обеих сторон баррикад. Его и в компиляторе, и в рантайме нужно запускать.


Олег: JIT — это и компилятор, и рантайм одновременно?


Иван: Да, можно и так сказать.


Никита: Получается, что специализация какая-то есть, но тебе очень часто приходится на границе работать и врубаться во все вокруг.


Олег: А расскажите, как выглядит день работника у вас в компании? Например, я мог бы рассказать распорядок дня веб-разработчика, но это ужасно, поэтому пропустим и перейдем сразу к вам.


Иван: На самом деле, не то, чтобы здесь было что-то супер-особенное. У нас есть какие-то цели, планы, которые мы можем сделать. Бывает, что план прописан четко. Бывает, что тебе просто нужно сделать какую-то задачу. Есть issue-трекер, в котором есть баги, которые нужно чинить. Ты приходишь, смотришь, какая у тебя самая горячая задача и начинаешь ей заниматься.


Из необычного, что отличает от других. Предположим, ты написал код — в рантайме, в компиляторе или ещё где-нибудь. Обычно после этого программист запускает и смотрит, работает ли. А у нас после этого нужно запустить check-in тест, который сам по себе идет 1.5-2 часа.


Никита: Раньше у нас исходники лежали в Visual Source Safe, и там коммит назывался check-in. Прежде чем ты мог в этот VSS зачекиниться, ты должен был пройти check-in тест. После нашего ухода с VSS, он до сих пор называется check-in тестом.


Иван: Это тест, где собирается весь JET, то есть вся JVM с твоими правками, прогоняются базовые тесты. Это занимает 1.5-2 часа. Только через это время у тебя будет готовый JET, чтобы попробовать, сработало или нет. Баг у тебя проявился в каком-то конкретном приложении, наверное, поэтому нужно потом скомпилировать это приложение, пройти сценарий и понять — сработало ли. Сколько у тебя попыток в день так сделать? Не так много. Поэтому мы стараемся сразу писать код качественно.


Олег: JET написан на Scala?


Иван: Один из компиляторов написан на Scala.


Сам JET компилятор написан на Scala, при этом он сам компилируется JET-ом. То есть он JET-ом предыдущей версии собирается. Получается экзешник, который потом используется. Представь, что сначала нужно взять Scala-исходники, по ним пройтись с помощью scalac, получится байткод…


Никита: Больше всего времени в этом check-in тесте занимает компиляция самой Java-платформы в машинный код, потому что ее нужно скомпилировать всю, а она здоровая, и она компилируется полтора часа.


Олег: Можно как-нибудь разбить на юниты и раскидать на сборочный кластер, ну как с C++ делают?


Никита: Хорошая идея, мы про нее периодически думаем. У меня есть идеи, как это сделать, но руки не доходят распараллелить нашу любимую компиляцию.


Иван: Из необычного еще в дне JVM-инженера — бывает так, что ты очень долго отлаживаешь какой-то баг, потому что он спорадичный. У меня был рекорд — баг проявлялся раз в год. Случилась беда, я вроде понял, что произошло, проверил — не проявилось, закоммитил. Прошел год, и он снова случился. Я его назвал «годовалый баг». Есть такая особенность. Надеюсь, что сейчас я его починил, но год еще не прошел, поэтому не знаю :-) Такие баги — это очень неприятно. У меня был довольно большой проект, связанный с GC, который из-за каких-то неучтенных случаев или ошибок мог вызывать огромное количество спорадичных багов. Ты узнаешь, что у тебя что-то пошло не так, только постфактум, когда смотришь на развалы. У тебя нет сценария воспроизведения, никакое стресс-тестирование тебе не поможет. Ничего вообще не помогает.


Олег: Что делать, обращаться к Кашпировскому?


Иван: Я в таких случаях оставляю ловушку. Понимаю, что конкретно произошло по текущему крэшлогу. Если это снова случится, то огромное количество информации по этой проблеме я распечатаю в отдельный файл. Потом говорю QA-инженеру, что если вдруг случится ещё раз — ищи этот файл, он очень важный. В нем новые подсказки, что конкретно пошло не так.


Олег: Эти ловушки никак на перформанс не влияют?


Иван: Я делаю их так, чтобы не влияли. Минимальный импакт, они начинают тратить перформанс, когда проблема случилось. Вроде, получается. C GC бывают очень разные проблемы. Это хорошо, если ты увидел, что у тебя какой-то объект битый. А проблема же может быть гораздо сложнее, GC что-то сделал не так — собрал объект или не собрал объект. В результате через два часа работы приложения у тебя случается какой-нибудь креш. Что это было? Что за метод?


Никита: Промахнулся в одном месте на один битик, и в следующий раз это случится неизвестно когда.


Иван: Тебе уже никакие логи, ни хип-дамп, ничего не поможет. Нет информации. Единственная информация, которая у тебя есть — что это однажды взорвалось. Тебе после этого можно только оставлять ловушки. В общем-то и всё.


Никита: Либо убеждать себя, что, наверное, пролетела из космоса частица и пробила память в одном бите.


Олег: А если он постоянно проявляется, можно что-то сделать?


Иван: Это какой-то очень простой баг, который мы быстро поправим.


Олег: А что с багами в JIT?


Никита: В JIT бывают простые баги. Посмотришь на assert, который случился, на стек-трейс, и становится ясно, что произошло. Тут же поправил.


Иван: Стоит сказать, что у нас очень хорошее тестирование. Мы JCK гоняем. Если что-то проходит JCK, это уже означает, что оно неплохо написано. Кроме того, у нас большое количество реальных приложений. В тестировании мы используем UI-тесты, которые протыкивают GUI-приложение, скомпилированные JET. Есть просто какие-то хитрые сценарии. Недавно мы делали тест, который брал конкретный проект с GitHub и начинал по одному коммиту чекаутить его и собирать JET-ом. Чекаутить следующий коммит и пересобирать JET-ом и так далее. У нас QA-отдел работает очень хорошо, всё отлично покрыто тестированием.


Олег: Тестировщик же должен понимать, что тестирует? Не окажется ли так, что квалификация тестировщика должна быть выше, чем квалификация разработчика?


Иван: У нас QA Lead — это рантайм-инженер. Он сейчас занимается еще и QA, но рантайм тоже пишет. Думаю, это довольно красноречиво. Да, он знает, что происходит и как должно быть. Как нужно тестировать, понимает специфику.


Олег: Сколько лет нужно потратить, чтобы стать QA в вашем проекте? Условно говоря, в вебе зачастую QA-шник, к сожалению, — должность с самой монотонной работой, на которой люди тыкают кнопки и смотрят, что они окрасились в синий цвет. У вас, вероятно, всё как-то по-другому.


Иван: Ситуация та же, что и с саппортом. Мы не можем нанять человека с улицы, чтобы он сидел на саппорте, потому что у него не хватит квалификации, поэтому мы сами становимся саппортами раз в какое-то время. Соответственно, QA Lead не пишет тесты постоянно, он руководит. И хотя руководит он не JVM-инженерами, сам он им является, это о многом говорит.


Олег: Как у вас выглядит тестирование? Есть какой-то заготовленный эталонный код, и QA-шники просто с ним сравнивают, если он отличается — то проблема?


Никита: У нас есть JCK, тесты от Oracle. Тестеры Oracle нам их поставляют, и это хорошо. Потому что практически на каждую букву спецификации написан какой-нибудь тест. Кроме JCK, обычно берутся какие-нибудь реальные приложения, компилируются, протыкиваются, и потом это протыкивание автоматизируется.


Олег: Что нужно, чтобы получить JCK?


Никита: Заплатить денег Oracle. Помимо этого, ты должен делать JVM, которая чем-то очень необычно отличается от той, что у Oracle.


Иван: Есть разные способы. Например, если ты вкладываешься в Open JDK, тебе дадут JCK.


Никита: Если тебе дали какую-то специальную звездочку, что ты не простой человек, а что-то уже сделал хорошее, то тебе да — наверное, дадут. Чтобы стать лицензиатом, тебе нужно доказать, что твой продукт как-то нетривиально отличается от продукта Oracle. Например, что он на платформе, которую Oracle не поддерживает.


Олег: А если тривиально отличается?


Никита: Тогда имеют право не дать. Нам удалось убедить, что мы что-то даём сверх имеющегося, это называется «value add». И нам дали JCK, в рамках коммерческой лицензии на Java, которая за деньги. Нам дали JCK и сказали, что если вы за три месяца его не пройдёте — то закрывайте лавочку.


Олег: Жесть какая! Почему бы тогда всем, кто делает форки OpenJDK, не собраться и не написать свой вариант?


Иван: Это довольно дорогая тема. Представь, что у тебя 70 тысяч тестов. У нас есть некоторый секретный набор тестов, которых нет в JCK, а может было бы неплохо, чтобы они там были, но мы их не публикуем. Потому что, может быть, и JET их не пройдет, и HotSpot их не пройдет. Есть такие тонкие места в спецификации.


Олег: Потом сделаете доклад про тонкие места спецификации? Это было бы интересно.


Никита: У меня с Мишей Быковым из Oracle был совместный доклад про поддержку JVM. Там я рассказал про некоторые тонкие места спецификации. Были «истории из жизни поддержки JVM» на конференции Joker.


Олег: Запись осталась?


Никита: Да, конечно. Насчет спецификации JVM. Вот реальный случай из недавнего: некоторые наши JVM-инженеры заметили, что код написан не по спецификации, и решили его переписать, затем прислали мне на ревью. Я читаю и понимаю, что в спецификации баг.


Олег: Может, в JCK баг?


Никита: Нет, в спецификации. Я его описание отослал в соответствующий mailing list, и Алекс Бакли (Alex Buckley), человек, который сейчас главный по Java/JVM-спецификациям, исправил этот баг в JVM Specification 12.


Иван: В JCK тоже бывают баги.


Никита: Когда мы начинали проходить JCK, мы пачками стали слать Sun некорректные тесты. Мы огромными простынями доказывали, что тест некорректный — а им приходилось эти некорректные тесты исключать.


Олег: Доказать некорректность теста — это чуть ли не сложнее, чем написать?


Никита: Конечно, сложнее. Очень кропотливая работа. Были, например, некорректные тесты на CORBA. Сидишь такой, сложный многотредовый тест куда-то ломится, и ты придумываешь и объясняешь разные ситуации. Я чуть ли не 6 страниц написал про то, почему тест на CORBA некорректный. Дело в том, что мультитредовая картинка может быть не такая, как на HotSpot, и надо доказать, что возможна такая ситуация, которую тест не ожидает.


Олег: Можно ли это сконвертировать в докторскую, шесть репортов — одна докторская?


Никита: Я две недели сидел и все выписывал. CORBA была обязательной частью, но сейчас её наконец выпилили. И Swing обязательный. В JCK есть автоматически тесты на Swing, а есть несколько сотен тестов, где нужно ручками все протыкать. И у нас после каждого релиза один выделенный человек садится и тыкает на каждой платформе все эти формочки.


Иван: Это называется «интерактивные тесты JCK».


Никита: Чтобы выпустить продукт, мы обязаны в любой момент предоставить доказательства, что JCK у нас проходит. И для этого нужно пройти эти интерактивные тесты.


Олег: Этого человека на видеокамеру пишут или что?


Никита: Нет, он проверяет, что всё работает, а потом результат криптуется так, что после этого результат является доказательством, что мы эти тесты реально проходили.


Олег: Просто можно было бы скрипт написать, который это делает.


Иван: В том-то и дело, что нет. Там есть те, которые роботами протыкиваются. Они тоже графические.


Олег: То есть там такие тесты, которые вообще не автоматизируемы?


Никита: Написано, что их нельзя проходить роботом.


Олег: То есть всё рассчитано на честность. Интересно, сколько кроме вас ещё таких честных. Вижу такую картину: проходит сто лет, вокруг всё делает искусственный интеллект. И у искусственного интеллекта есть один человек, которой проходит JCK, потому что всё написано на Java.


У меня ощущение, что надо закругляться. Неплохо бы нам придумать какое-нибудь послесловие и пожелание читателям.


Никита: Занимайтесь интересными делами — это драйвит. Неважно, что ты делаешь, если тебе это нравится — это замечательно. Моя мотивация работать в этом проекте заключается в том, что с годами почему-то интересные задачи не кончаются. Постоянно челленджи, челлендж на челлендже. Я бы посоветовал всем искать работу с челленджами, потому что тогда тебе веселее жить.


Олег: Это как-то связано с тем, что вся работа связана с виртуальными машинами или с системным программированием? Почему челленж?


Никита: Виртуальные машины — это постоянное исследование. Конечно, какой-нибудь С-шный компилятор ты двадцать лет делать не будешь, потому что там все-таки когда-нибудь кончатся новые знания. А с Java они почему-то не кончаются! До сих пор не понятно, как делать правильно GC. Как правильно делать компилятор — тоже до сих пор никому не понятно — ни хотспотовцам, ни нам.


Иван: Это не просто исследование, это передовой край всякой компиляторной, рантаймовской науки. У нас сейчас ребята переделывают бэкенд компилятора и для этого разбирают новейшие научные статьи (понятно, что для реальной JVM они требуют адаптации и дополнения). Обычно ты прочитал статью, и что? А ничего. В статье описывается прототип, кто-то чего-то измерил на нем, и все. А здесь есть возможность реализовать это на настоящей JVM и посмотреть, как это будет себя вести на практике. Это очень круто, мало где в мире есть такая возможность.


Сейчас в Java происходит много всего крутого. Все это ускорение релизов, мегапроекты, которые сейчас появляются — все они очень клевые. Тот же Loom и Metropolis, это такие очень основательные и очень прикольные проекты в экосистеме Java. Даже без привязки к какой-то конкретной JVM, смысл просто в том, что прогресс прет вперед, это круто, и за этим надо смотреть, разбираться и восхищаться. Посмотрите доклад про Loom и просто посмотрите, как он себя ведет на практике, что такие прототипы работают. Это дает надежду на будущее. Поэтому я напоследок всех призываю не только следить за новыми технологиями и разбираться в них, но и участвовать в их развитии — всё это реально очень круто.


Минутка рекламы. Раз вы дочитали досюда, вам явно очень важна Java — поэтому вам стоит знать, что 5-6 апреля в Москве состоится Java-конференция JPoint. Там как раз выступит Никита Липский, а также другие известные Java-спикеры (Simon Ritter, Rafael Winterhalter). Вы тоже можете подать заявку на доклад и попробовать себя в качестве спикера, Call for Papers открыт до 31 января. Увидеть актуальную информацию о программе и приобрести билеты можно на официальном сайте конференции. Чтобы оценить качество остальных докладов с прошлой конференции, можно посмотреть архив видеозаписей на YouTube. Встретимся на JPoint!

Комментарии (9)


  1. BugM
    24.01.2019 14:00

    Современный JIT великолепен. После прогрева он выдает результат отличающийся от идеально сферического на считанные проценты. А где ваши тесты быстродействия можно посмотреть?


    1. dbg_nsk
      24.01.2019 17:09

      Например, вот: github.com/excelsior-oss/excelsior-jet-samples/tree/master/pgo-bench. Но это, конечно же, весьма искусственный пример. И в этом проблема всех бенчей — они показывают ровно то, для чего созданы, а общую картину по ним понять не получится.

      Производительность же реального приложения зависит от множества факторов: плоский или нет профиль, насколько большая нагрузка на GC, какой размер кучи, важна нам производительность на старте или после прогрева, готовы ли мы использовать PGO и т.д.

      Поэтому у нас нет какого-то публичного набора бенчей, который бы мы всем демонстрировали (приватные, конечно, есть, используем их для контроля изменения производительности во время разработки). Вместо этого мы всегда предлагаем людям взять свое приложение, скомпилировать JET-ом, прогнать типичный сценарий и посмотреть, что с производительностью. В зависимости от характера приложения производительность может улучшаться или ухудшаться по сравнению, например, с HS.


  1. ipswitch
    24.01.2019 14:31
    +2

    Какое чудо. Лет 8-10 назад видел демо-версию данного продукта, кажется, на CD приложении к журналу «Хакер». Даже не подумал бы, что это новосибирская разработка. Славная земля, породившая 2ГИС, OpenVZ и Parallels…


    1. cypok
      24.01.2019 16:23

      А еще "Дальнобойщиков" в соседнем институте делали. :)


  1. ipswitch
    24.01.2019 14:40
    +2

    Удачи ребятам и продукту. Честно подняло настроение и веру в светлые умы отечественных разработчиков. Да и интервью читается легко, написано с душой. Много интересных подробностей «внутренней кухни» разработки и тестирования, а также взаимодействия с Sun/Oracle.
    Спасибо за статью!


  1. SiliconValleyHobo
    26.01.2019 10:30
    +1

    По поводу комментария о разных архитектурах: на arm может барьеров и больше надо, чем на х86, но это только для атомиков с последовательной консистентностью.
    Более того, правильно написанный С++ код и модель памяти С++ полностью скрывает эти самые барьеры от программиста. Т.е. гемороя буквально никакого.
    Но вот Х86 имеет нехилый оверхед в тех случаях, когда последовательная консистентность не нужна. Утрированно, в них барьеры неявно включены. А значит, реально для арма с точки зрения программиста гемороя нету, а работает он в общем случае быстрее. Ну не сказка ли?


  1. ksdaemon
    26.01.2019 12:21
    +2

    Хорошее интервью!
    А для тех кто предпочитает аудио версию, или просто интересно, можно послушать SDCast #95 с Никитой, Иваном и Павлом.


  1. Danik-ik
    26.01.2019 15:01
    +1

    Вау. А возможно ли сделать на этом dll? Чтобы плагин для нативного легаси-приложения получился.


    1. FOODzee
      26.01.2019 20:33
      +1

      Можно :)
      Там, правда, нужно немного поприседать, чтобы корректно JVM разогнать, но для этого есть ворох сэмплов в дистрибутиве JET'а:
      samples