Суровая сибирская JVM: большое интервью об Excelsior JET +54


Недавно мы писали о том, на какие ухищрения пошла 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!




К сожалению, не доступен сервер mySQL