Краткое описание проблемы:
Был распространенный метод Java (скажем, methodCausingProblem (), скомпилированный размер которого составляет около 4 КБ), используемый для всех запросов, в которых мы столкнулись с некоторым внутренним скачком памяти (около 2 ГБ) во время C2сборник. Странной вещью в этом методе была лямбда-функция. После удаления этого подозрительного кода проблема, казалось, была решена. Но мы до сих пор не можем найти истинную причину скачков памяти
Путь отладки:
С помощью встроенного отслеживания памяти, профилировщиков (perf и jem), ядраАнализаторы дампов (gdb и hsdb) позволили выявить проблемный метод.
public static void methodCausingProblem() {
// some content
DefaultValue obj=() -> mymethod("Dummy");
String data=obj.func();
// some content
}
public static String mymethod(String rel) throws Exception{
return rel;
}
public static interface DefaultValue {
String func() throws Exception;
}
Дополнительные сведения о проблеме:
При анализе с использованием профилировщиков рост памяти происходил во время PhaseChaitin Register_Allocationи мы не смогли найти ничего подозрительного в соответствующем машинном коде. Насколько нам известно, это некоторая оптимизация, основанная на проверке разлива и принятии решения о распределении регистров.
Собственная трассировка стека, которая заняла больше памяти:
_ZNK4Node13rematerializeEv + 0x20
_ZN12PhaseChaitin5SplitEjP12ResourceArea + 0x9a0
_ZN12PhaseChaitin17Register_AllocateEv + 0x9fd
_ZN7Compile8Code_GenEv + 0x2bb
_ZN7CompileC1EP5ciEnvP10C2CompilerP8ciMethodibbb + 0x1260
_ZN10C2Compiler14compile_methodEP5ciEnvP8ciMethodi + 0x20c
_ZN13CompileBroker25invoke_compiler_on_methodEP11CompileTask + 0xd46
_ZN13CompileBroker20compiler_thread_loopEv + 0x657
_ZN10JavaThread17thread_main_innerEv + 0xf1
_ZL10java_startP6Thread + 0x132
Perf snapshot
Событие компиляции:
<nmethod compile_id='32976' compiler='C2' level='4' entry='<hex>' size='444608' address='<hex>' relocation_offset='296' insts_offset='23920' stub_offset='251280' scopes_data_offset='266328' scopes_pcs_offset='341304' dependencies_offset='418600' handler_table_offset='418832' nul_chk_table_offset='443168' oops_offset='265072' method='<problematicMethod(arg1..argn)>' bytes='4191' count='1295' backedge_count='17962' iicount='1295' stamp='1042.504'/>
- Отредактировано -
В нашем приложении много лямбда-функций, но только в этом месте возникла проблема. Мы хотим углубиться в этот метод, чтобы определить актуальную проблему, чтобы остановить такие проблемы в будущем.
Есть идеи для более глубокой отладки?
- Обновлено -
Собственный рост памяти происходит только тогда, когда лямбда-метод вызывается в определенной точке уязвимого метода.