АРХИВА 10 Help

Неожиданная остановка JVM-процесса (Linux)

При работе на enterprise-сервере под управлением Linux и большой JVM (десятки гигабайт heap, DirectMemory, ZGC и т.д.) процесс может неожиданно завершаться. Причины могут быть как в самой JVM, так и во внешней среде (ядро, мониторинг, лимиты). Ниже объединены рекомендации по диагностике и предотвращению таких падений.

1. Проверить логи ядра (dmesg и /var/log/kern.log)

Частая причина — OOM Killer или аппаратные/системные ошибки.

dmesg | grep -i "killed" dmesg | grep -i "segfault" dmesg | grep -i "oom" # Out of Memory journalctl -k | grep -i "killed" cat /var/log/kern.log | grep -i "killed"

Пример вывода при нехватке памяти:

Out of memory: Kill process 1234 (java) score 987 or sacrifice child Killed process 1234 (java)

2. Проверить системные логи (/var/log/syslog, journalctl)

journalctl -xe | grep java cat /var/log/syslog | grep java

3. Проверить, был ли процесс убит OOM Killer

grep -i "oom" /var/log/syslog grep -i "killed process" /var/log/syslog

4. Проверить ограничения (ulimit, cgroups, systemd`)

  • ulimit:

    ulimit -a
  • cgroups:

    systemd-cgtop
  • systemd:

    systemctl status archiva.service journalctl -u archiva.service -xe

Если OOMKilled=yes → ядро или systemd принудительно завершили процесс.

5. Проверить сигналы и трассировку

  • Если процесс падает по SIGSEGV, SIGBUS или SIGILL, в каталоге будет hs_err_pid*.log.

  • Для живого процесса:

    strace -p PID
  • Для запуска с нуля:

    strace ./startup.sh

6. Проверить внешнее завершение (мониторинг, supervisor, cron)

  • Использовать pstree для иерархии процессов.

  • Проверить auditd, если есть подозрение на внешние kill-сигналы.

7. Проверить использование памяти и CPU

top -p PID htop vmstat 1 free -h smem -rs swap
  • Если si/so (swap in/out) активно растут → JVM страдает от свопа.

  • Если Java в smem занимает десятки гигабайт swap → heap выгружен ядром.

8. Проверить SELinux / AppArmor

grep "avc:" /var/log/audit/audit.log journalctl | grep "apparmor"

9. Специфика JVM (enterprise-сценарий)

Основные риски

  • OOM Killer ядра: когда JVM (heap + DirectMemory + native + metaspace) превысила RAM + swap.

  • GC завис из-за swap: страницы heap в swap → ZGC/GC начинают работать с диском, приложение подвисает → мониторинг/systemd убивает процесс.

Что делать

  1. Понизить swappiness:

    sysctl -w vm.swappiness=1 echo 'vm.swappiness=1' >> /etc/sysctl.conf

    → снизит вероятность выгрузки heap в swap.

  2. Включить GC-логи:

    -Xlog:gc*,gc+cpu=debug,gc+heap=debug:file=/var/opt/mailarchiva/logs/gc.log:time,uptime,level,tags

    → анализировать ZGC-паузы и нагрузку.

  3. Следить за native memory: Добавить:

    -XX:NativeMemoryTracking=summary -XX:+UnlockDiagnosticVMOptions -XX:+PrintNMTStatistics

    → при остановке JVM будет видно, куда ушла native-память.

  4. Проверять OOM Killer:

    dmesg | grep -i kill journalctl -k | grep -i kill
  5. Уточнить лимиты systemd:

    • MemoryMax=, LimitNOFILE= и пр. в unit-файле сервиса.

    • При ограничениях контейнера (Docker/K8s) проверить --memory и --memory-swap.

Выводы

  • Если процесс убит OOM Killer → уменьшить heap/DirectMemory, увеличить RAM или снизить swappiness.

  • Если процесс падает с SIGSEGV и есть hs_err_pid → отладка JNI/библиотек, проверить JDK.

  • Если процесс зависает из-за swap → ограничить swap, оптимизировать GC и настройки памяти.

  • Если проблема в лимитах (ulimit, cgroups) → увеличить лимиты или изменить unit-файл.

  • Если виноват мониторинг/systemd watchdog → проверить настройки health-check.

Таким образом, диагностика падения JVM сводится к анализу логов ядра, системных логов, ограничений окружения и GC-логов. Для enterprise-нагрузки критично минимизировать работу со swap и контролировать распределение памяти между heap, DirectMemory и native-кодом.

30 September 2025