Я написал серверное приложение в 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, что могло бы произойти это?