Pull to refresh

Comments 15

Хе-хе.
Андрей, твои статьи нужно предварять дисклеймером:
Известно, что C++ дает девелоперам полную свободу, по отстрелу ног. Но мы в Java ни чем не хуже — читайте свежую статью из цикла «1000 и 1 выстрел в ногу из Java.»
:))))
Ага. Зато есть, о чем потом на конференции рассказать :) Вот, на ближайшем Joker как раз доклад на тему, как разбирать последствия таких выстрелов :)
То есть получается примерно так:
«Дети, вот шкафчик с оружием. Код на замке: 42. А теперь я научу вас как по траектории разлета мозгов определить калибр.» ;)))))
Как Java подхватывает такое «переключение» флага? Особенно если оно требует перераспределение памяти, дополнительную инициализацию, создание внутренних структур (флаги не просто так задаются при старте JVM).
Разумеется, не все флаги получится менять на лету. Многие из них обрабатываются лишь один раз на старте JVM. В частности, все, что касается размеров Java Heap, выбора сборщика мусора и т.п. Эффект будет лишь от смены тех флагов, которые проверяются постоянно, например, различные опции трассировки. По-хорошему, все их надо сделать manageable, тогда и не придется плясать с бубном.
Надо попробовать поменять флаг используемого компилятора (-server) в рантайм. Интересно посмотреть на «траекторию разлета мозгов»
Не выйдет.
-client / -server вообще не являются флагами JVM.
До JDK 7 эти параметры разбирал launcher (иначе говоря, запускаемый бинарник) и выбирал соответствующую версию libjvm.

Начиная с JDK 7 «серверная» библиотека libjvm включает в себя оба компилятора: C1 и C2. Есть возможность включить так называемую ступенчатую компиляцию ключиком -XX:+TieredCompilation. Но только из командной строки. Установка флага в runtime ни к чему не приведет, т.к. для поддержки ступенчатой компиляции требуется модифицированная версия интерпретатора байткода, которая генерируется лишь единожды при запуске JVM.
Да, я уже попробовал — сразу увидел что символа такого нет. Всё равно интересно получается и можно много чего сделать. Если интересно, код тут: github.com/voronaam/jflag
Попробовал менять «StackTraceInThrowable» в рантайме. Не получилось. А жаль, вот этим параметром как раз было бы отлично в райнтайме управлять.

Но то есть получилось, но при генерирование OutOfMemory exception прилетел SIGSEGV.

На этом я пока остановлюсь. Удалось сегфолт словить и достаточно.
Проверил у себя — получилось успешно. На каком примере и на какой версии SIGSEGV валится?

С OutOfMemoryError и StackOverflowError есть особенность, что они преаллоцируются на старте JVM (иначе при попытке выполнения честного конструктора может не хватить памяти или стека). Поэтому, например, если запустили Java с -XX:-StackTraceInThrowable, а потом в рантайме выставили в true, то эти ошибки все равно вылетят без трейса.
Проверил сейчас: с Oracle JDK работает, на OpenJDK падает. Больше деталей тут.

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

В детали сегфолта я не вдавался, но как мне показалось OpenJDK попыталась всё-таки раскрутить стэк эксепшена при печати его на экран. А сам throw — catch прошёл без нареканий.
Опять же, никаких хаков, только чистая Java.

Хорошая фраза в теле описания большущего хака. Повеселил.
Забавно делать препарирование своего нативного окружения. Следующий шаг: «Чисто Java: Подмена нижележащей ОС (или хоста!) на лету.»

Если не секрет, то, реально интересно, что послужило толчком к поиску именно такого, скажем прямо, нетрадиционного решения? Т.е. какой JVM флаг (не из набора manageable) нестерпимо захотелось менять во время выполнения программы без её рестарта?
Если не секрет, то, реально интересно, что послужило толчком к поиску именно такого, скажем прямо, нетрадиционного решения?

Любознательность :) На самом деле, острой необходимости и не было. Пару раз возникало желание включить/выключить на лету TraceClassLoading, TraceClassUnloading и PrintCompilation. Или еще один раз проверить эффект от смены hashCode под нагрузкой. Но в итоге на production серверы все равно такой хак решили не внедрять.
А каким был эффект смены на лету hashCode под нагрузкой на тестовых?
На сервере с бизнес-логикой — всего 1% прироста к производительности. На синтетических тестах на сериализацию — порядка 30%.
Sign up to leave a comment.