Подтвердить что ты не робот

Java 8 JIT поток, похоже, попадает в бесконечный цикл

Я написал серверное приложение в Java 8 и запустил его с помощью java 1.8.0u25.

Он работает отлично в течение первых нескольких часов, но после того, как он получает запросы порядка 5k ~ 10k, поток процесса VM использует 100% одного из процессоров.

Итак, я попробовал jstack для процесса VM проверить, что представляет собой проблемный поток, и показал, что поток (идентификатор потока был 14303 = 0x37df) был "C2 CompilerThread0":

"C2 CompilerThread0" #6 daemon prio=9 os_prio=0 tid=0x00002aaabc12a000 nid=0x37df runnable [0x0000000000000000]
   java.lang.Thread.State: RUNNABLE

И с jstack -m трассировка стека потока была следующей:

----------------- 14303 -----------------
0x00002b99b67693c3  _ZN16PhaseMacroExpand27process_users_of_allocationEP8CallNode + 0x2a3
0x00002b99b676ec3b  _ZN16PhaseMacroExpand23eliminate_allocate_nodeEP12AllocateNode + 0x1cb
0x00002b99b676ee65  _ZN16PhaseMacroExpand21eliminate_macro_nodesEv + 0x1a5
0x00002b99b6772769  _ZN16PhaseMacroExpand18expand_macro_nodesEv + 0x19
0x00002b99b640b01b  _ZN7Compile8OptimizeEv + 0xa6b
0x00002b99b640c53c  _ZN7CompileC1EP5ciEnvP10C2CompilerP8ciMethodibbb + 0x13bc
0x00002b99b635f9c8  _ZN10C2Compiler14compile_methodEP5ciEnvP8ciMethodi + 0x198
0x00002b99b6414c6a  _ZN13CompileBroker25invoke_compiler_on_methodEP11CompileTask + 0xc8a
0x00002b99b6417650  _ZN13CompileBroker20compiler_thread_loopEv + 0x620
0x00002b99b69a2e8f  _ZN10JavaThread17thread_main_innerEv + 0xdf
0x00002b99b69a2fbc  _ZN10JavaThread3runEv + 0x11c
0x00002b99b6860d48  _ZL10java_startP6Thread + 0x108

И каждый раз, когда я пробовал jstack -m, трассировка стека этого потока была одинаковой, но число рядом с методом (счетчик программ?) в верхней части стека _ZN16PhaseMacroExpand27process_users_of_allocationEP8CallNode составляло 0x290, 0x2b1, 0x2a3 или 0x29f.

C2 CompilerThread0 выглядит как поток, выполняющий компиляцию JIT, и трассировка стека кажется, что она попала в бесконечный цикл или что-то в этом роде.

Интересно, может ли это быть ошибкой JIT-компилятора JVM. Если да, как я могу указать, какой метод моего приложения делает сумасшедшую JVM и как я могу решить (или обойти) эту проблему? Я попробовал параметр -XX:+PrintCompilation, но это не помогло, потому что он не показывал, какой поток скомпилировал какой метод. Если это не проблема JVM, что могло бы произойти это?

4b9b3361

Ответ 1

Он действительно выглядит как ошибка компилятора JIT, предположительно в оптимизации устранения выделения.
Попробуйте запустить с опцией -XX:-EliminateAllocations JVM.

Вы также можете добавить -XX:+UnlockDiagnosticVMOptions -XX:+LogCompilation, чтобы создать подробный журнал компиляции с отдельным выходным файлом в потоке компилятора.