Полезен ли Java-файл corefile, сгенерированный с помощью gcore? - PullRequest
2 голосов
/ 30 октября 2019

У нас есть JAVA приложение, которое сбивает наш redhat сервер (30 ядер / 512Go ram) из-за использования некоторых (неизвестных?) Ресурсов, не позволяющих другим компонентам создавать новые потоки. В настоящее время мы работаем над этим, убивая процесс, который спамит потоки каждый раз, когда возникает проблема, и примерно каждые 15 дней, мы пытались установить огромные значения в / etc / security / limit.conf , но мырешить проблему до достижения этого предела.

Я подсчитал потоки в последний раз, когда это произошло, используя ps -efL |wc -l , является ли 10000 многозадачным для нашего зверя, зная, что в этот момент потребление ЦП / ОЗУ было низким? Я использовал gstack , чтобы попытаться выяснить, где он застрял, но так как это ИДК программы JAVA, если вывод имеет смысл? но я мог бы определить образец там: большинство из 9000 потоков выглядят так:

Thread 9049 (Thread 0x7f43d5087700 (LWP 123925)):
#0  0x00007f43d791e705 in pthread_cond_wait@@GLIBC_2.3.2 () from /lib64/libpthread.so.0
#1  0x00007f43d6a94f33 in os::PlatformEvent::park() () from /opt/3pp/jdk1.8.0_25/jre/lib/amd64/server/libjvm.so
#2  0x00007f43d6a58e67 in Monitor::IWait(Thread*, long) () from /opt/3pp/jdk1.8.0_25/jre/lib/amd64/server/libjvm.so
#3  0x00007f43d6a59786 in Monitor::wait(bool, long, bool) () from /opt/3pp/jdk1.8.0_25/jre/lib/amd64/server/libjvm.so
#4  0x00007f43d6c48e1b in GangWorker::loop() () from /opt/3pp/jdk1.8.0_25/jre/lib/amd64/server/libjvm.so
#5  0x00007f43d6a9bd48 in java_start(Thread*) () from /opt/3pp/jdk1.8.0_25/jre/lib/amd64/server/libjvm.so
#6  0x00007f43d791adf5 in start_thread () from /lib64/libpthread.so.0
#7  0x00007f43d722f1ad in clone () from /lib64/libc.so.6
Thread 9048 (Thread 0x7f43d4f86700 (LWP 123926)):
#0  0x00007f43d791e705 in pthread_cond_wait@@GLIBC_2.3.2 () from /lib64/libpthread.so.0
#1  0x00007f43d6a94f33 in os::PlatformEvent::park() () from /opt/3pp/jdk1.8.0_25/jre/lib/amd64/server/libjvm.so
#2  0x00007f43d6a58e67 in Monitor::IWait(Thread*, long) () from /opt/3pp/jdk1.8.0_25/jre/lib/amd64/server/libjvm.so
#3  0x00007f43d6a59786 in Monitor::wait(bool, long, bool) () from /opt/3pp/jdk1.8.0_25/jre/lib/amd64/server/libjvm.so
#4  0x00007f43d6c48e1b in GangWorker::loop() () from /opt/3pp/jdk1.8.0_25/jre/lib/amd64/server/libjvm.so
#5  0x00007f43d6a9bd48 in java_start(Thread*) () from /opt/3pp/jdk1.8.0_25/jre/lib/amd64/server/libjvm.so
#6  0x00007f43d791adf5 in start_thread () from /lib64/libpthread.so.0
#7  0x00007f43d722f1ad in clone () from /lib64/libc.so.6

Также перед тем, как убить процесс, я использовал gcore -o /tmp/dump.txt ,это правильный способ получить corefile java-процесса?

Когда я пытаюсь посмотреть, используя gdb , я получаю без отладочных символов и нетдамп ядра , это правильный способ проверки файлов такого типа?

M1:~# gdb /opt/3pp/jre/bin/java /tmp/dump.txt.123913 
GNU gdb (GDB) 
Copyright (C) 2013 Free Software Foundation, Inc.
License GPLv3+: GNU GPL version 3 or later <http://gnu.org/licenses/gpl.html>
This is free software: you are free to change and redistribute it.
There is NO WARRANTY, to the extent permitted by law.  Type "show copying"
and "show warranty" for details.
This GDB was configured as "x86_64-redhat-linux-gnu".
For bug reporting instructions, please see:
<http://www.gnu.org/software/gdb/bugs/>...
Reading symbols from /opt/3pp/jre/bin/java...(no debugging symbols 
"/tmp/dump.txt.123913" is not a core dump: File format not recognized
Missing separate debuginfos, use: debuginfo-install jre1.8.0_25-1.8.0_25-fcs.x86_64

Заранее спасибо за ваше время.

Ответы [ 2 ]

1 голос
/ 30 октября 2019

Я подсчитал потоки в последний раз, когда это произошло, используя ps -efL |wc -l, много ли 10000 потоков для нашего зверя, зная, что в этот момент потребление CPU / RAM было низким?

Это немалое количество потоков, но нет, 10K потоков - это не , а много, особенно для 30-ядерных компьютеров. 4-ядерный рабочий стол Windows, на котором я сейчас работаю, имеет ~ 3K.

Я использовал gstack, чтобы попытаться выяснить, где он застрял, но так как это ИДК программы JAVA, если вывод имеет смысл?

Я никогда не пытался отлаживать Java с помощью собственных стеков потоков, но эта трассировка стека, на мой взгляд, выглядит как «припаркованная» нить. Другими словами, поток в каком-то пуле потоков, который не имеет ничего общего, поэтому он ждет работы. См. этот ответ для получения более подробной информации.

Также перед тем, как убить процесс, я использовал gcore -o /tmp/dump.txt, это правильный способ получить corefile файлаJava-процесс?

Вероятно, он имеет какое-то значение, но я бы предложил использовать для этой работы специфичные для Java инструменты. Первое, что приходит на ум, это jcmd, который идет с JDK. Вот ссылка , с которой можно начать. Версия Java 9 имеет некоторую лучшую документацию и очень похожа.

Что бы я конкретно сделал, это использовал команду Thread.print jcmd для печати трассировок стека java-уровня иGC.heap_dump для сброса всей кучи Java в файл .hprof, который впоследствии можно проанализировать с помощью таких инструментов, как MAT .

Если вы используете JDK 8 с «Коммерческие функции» , вы также можете включить JFR (Java Flight Recorder , который отслеживает выполнение процесса. Файлы, созданные JFR, могут быть открыты либо с помощью Oracle's Mission Control", или альтернативный" Mission Control ", такой как от Azul, называемый Zulu .

Наконец, вы также можете попытаться подключиться к процессу, используя jconsole , еще один инструмент, поставляемый с JDK.

Удачи.

0 голосов
/ 30 октября 2019

Я дам вам общий совет относительно файлов ядра JVM, чтобы вы могли выбрать, копать в него или нет.

Полезен ли файл Java-кода, созданный с использованием gcore?

Это полезно, но если вы не знаете о конкретной реализации JVM, это будет выглядеть как беспорядок. Трассировки стека полностью в порядке, и сбой определенно не произошел из-за вызова pthread_cond_wait (если только сам pthread не глючит, что крайне маловероятно).

У нас есть приложение JAVA, которое аварийно завершает работу

Вы запустили тест памяти? Реализация JVM HotSpot очень надежна в подавляющем большинстве случаев.

это правильный способ получить corefile процесса java?

Вы также можете использовать generate-core-file в gdb

нет символов отладки

Вы уже показали трассировку стека с символами отладки. Возможно, что-то не так с основным файлом. Попробуйте gdb generate-core-file

В случае, если вы хотите копаться в дамп ядра HotSpot, я мог бы посоветовать следующую последовательность действий:

  1. info threads, чтобы найти «ветку аварийного отказа». "
  2. Перейти к этой теме с thread N, где N - номер" аварийной нити "
  3. disas, чтобы отключить функцию и выяснить, какая команда вызвала сбой
  4. В случае, если это просто произошло из-за разыменования указателя мусора, переверните его вниз, чтобы выяснить, откуда берется значение

Ситуация усложняется, если вы столкнулись с чем-то вроде Bus Error из-за неверного mmap использование или около того. Ситуация становится еще сложнее, если вы потерпели крах в JIT-скомпилированном методе, поэтому bt, disas и друзья не будут полезны. Возможный способ - сбросить скомпилированный код из nmethod с помощью code_offset и попытаться выяснить, что пошло не так.

...