Проблемный фрейм JVM Crash: Canonicalizer::do_If
Я сталкиваюсь с крахом JVM при включении "горячего" развертывания (ИСПОЛЬЗУЯ ниже параметров Java при запуске JAVA_OPTS -Xmx4096m -XX:MetaspaceSize=512m -XX:+HeapDumpOnOutOfMemoryError -XX:HeapDumpPath=crash -XXX + 5X-SXS: UseSack-XS: ThreadSXGS: ThreadS ParallelGCThreads=5 -XX:NewRatio=2 -XX:+UnlockDiagnosticVMOptions -XX:-UseLoopPredicate -Xdebug -Xrunjdwp:transport=dt_socket,address=$DEBUG_PORT,server=y,suspend=n -XX:NewDsize.spr = = true JAVA_OPTS = `echo $ JAVA_OPTS -Dspringloaded.synchronize = true -javaagent: springloaded-1.2.1.jar -noverify)
Окружающая среда: JDK 1.8 U 66, RHEL 6.7
# # Фатальная ошибка была обнаружена средой выполнения Java: # # SIGSEGV (0xb) при pc=0x00007faee9a1e27c, pid=27208, tid=140379827795712 # # Версия JRE: среда выполнения Java(TM) SE (8.0_66-b17) (сборка 1.8.0_66-b17) # Java VM: 64-разрядная серверная виртуальная машина Java HotSpot(TM) (смешанный режим 25.66-b17 linux-amd64) # Проблемная рамка: # V [libjvm.so+0x35027c] Canonicalizer::do_If(If*)+0x1c # # Основной дамп написан. Расположение по умолчанию: core.27208 # # Файл отчета об ошибке с дополнительной информацией сохраняется как: # hs_err_pid27208.log # [таймер истек, прервать... ]
3 ответа
Я заметил оба -javaagent
а также -noverify
в списке опций Java.
Это выглядит как springloaded
Агент генерирует неверный байт-код, в то время как проверка байт-кода явно отключена. Не удивительно, что это может привести к непредсказуемым результатам, включая сбой JVM.
Это не проблема JVM, но, скорее всего, ошибка в springloaded
агент. Попробуй удалить -noverify
вариант.
-XX:-TieredCompilation
может также обойти эту конкретную проблему, но не ожидайте, что приложение будет работать правильно, если байт-код не прошел проверку. Лучше держаться подальше от библиотек с ошибочными агентами.
4.2.1 Сбой в потоке компилятора HotSpot или скомпилированного кода
Если журнал фатальных ошибок указывает, что сбой произошел в потоке компилятора, то возможно (но не всегда), что вы столкнулись с ошибкой компилятора. Аналогично, если сбой происходит в скомпилированном коде, возможно, компилятор сгенерировал неверный код.
В случае клиентской виртуальной машины HotSpot (опция -client) поток компилятора отображается в журнале ошибок как CompilerThread0. В виртуальной машине сервера HotSpot имеется несколько потоков компилятора, которые отображаются в файле журнала ошибок как CompilerThread0, CompilerThread1 и AdapterThread.
Ниже приведен фрагмент журнала ошибок для ошибки компилятора, которая была обнаружена и исправлена во время разработки J2SE 5.0. Файл журнала показывает, что виртуальная машина сервера HotSpot используется и произошел сбой в CompilerThread1. Кроме того, файл журнала показывает, что Current CompileTask была компиляцией метода java.lang.Thread.setPriority.
Виртуальная машина HotSpot обнаружила непредвиденную ошибку:: Java VM: виртуальная машина сервера Java HotSpot(TM) (смешанный режим 1,5-внутренней отладки): --------------- T H R E A D --------------
Текущий поток (0x001e9350): демон JavaThread "CompilerThread1" [_thread_in_vm, id=20]
Стек: [0xb2500000,0xb2580000), sp=0xb257e500, свободное пространство =505k Собственные кадры: (J= скомпилированный код Java, j= интерпретированный, Vv= код VM, C= собственный код) V [libjvm.so+0xc3b13c]:
Текущий CompileTask: опто: 11 java.lang.Thread.setPriority(I)V (53 байта)
--------------- ПРОЦЕСС ---------------
Потоки Java: ( => текущий поток) 0x00229930 Демон JavaThread "Low Memory Detector" [_thread_blocked, id=21] =>0x001e9350 Демон JavaThread "CompilerThread1" [_thread_in_vm, id=20]:
В этом случае есть два возможных обходных пути:
The brute force approach: change the configuration so that the application is run with the -client option to specify the HotSpot
Клиент ВМ.
Assume that the bug only occurs during the compilation of the setPriority method and exclude this method from compilation.
Первый подход (использование опции -client) может быть тривиальным для настройки в некоторых средах. В других случаях может быть сложнее, если конфигурация сложная или если командная строка для настройки виртуальной машины недоступна. Как правило, переключение с виртуальной машины HotSpot Server на клиентскую виртуальную машину HotSpot также снижает пиковую производительность приложения. В зависимости от среды это может быть приемлемо, пока фактическая проблема не будет диагностирована и устранена.
Второй подход (исключить метод из компиляции) требует создания файла.hotspot_compiler в рабочем каталоге приложения. Ниже приведен пример этого файла:
исключить java/lang/Thread setPriority
В общем случае формат этого файла исключает метод CLASS, где CLASS - это класс (полностью определенный с именем пакета), а METHOD - имя метода. Методы конструктора указываются как, а статические инициализаторы - как.
Примечание. Файл.hotspot_compiler является неподдерживаемым интерфейсом. Это задокументировано здесь исключительно в целях устранения неполадок и поиска временного обходного пути.
После перезапуска приложения компилятор не будет пытаться скомпилировать ни один из методов, перечисленных как исключенные в файле.hotspot_compiler. В некоторых случаях это может обеспечить временное облегчение, пока не будет диагностирована основная причина сбоя и исправлена ошибка.
Чтобы убедиться, что виртуальная машина HotSpot правильно обнаружила и обработала файл.hotspot_compiler, показанный в примере выше, во время выполнения найдите следующую информацию журнала. Обратите внимание, что разделитель имени файла является точкой, а не косой чертой.
Исключая компиляцию: java.lang.Thread::setPriority
Согласитесь с @apangin, в программе вы выполняете байт-код (-agent), но указывает -noverify. Когда проверка выключена, вы можете столкнуться с такими сбоями.
Вы не должны использовать -noverify или -Xverify:none во время внедрения байт-кода.
Для тех из вас, кто не знаком с проверкой байт-кода, это просто часть процесса загрузки классов JVM, который проверяет код на наличие определенных опасных и запрещенных действий. Вы можете (но не должны) отключить эту защиту во многих JVM, добавив -Xverify:none или -noverify в командную строку Java. https://blogs.oracle.com/buck/entry/never_disable_bytecode_verification_in