Надеюсь, вы поможете мне со следующей проблемой.
Мы запускаем службу CrushFTP в системе CentOS версии 6.6 (Final). Но почти каждую неделю сервис дает сбой.
Я просмотрел журналы и нашел эти строки
cat /var/log/messages
Jun 28 05:06:23 crushftp kernel: Out of memory: Kill process 1491 (java) score 883 or sacrifice child
Jun 28 05:06:23 crushftp kernel: Killed process 1491, UID 0, (java) total-vm:9620220kB, anon-rss:3245824kB, file-rss:128kB
CrushFTP - это java и единственный сервис, который мы запускаем на машине. Журнал выглядит так, будто система убивает процесс.
Но я не понимаю почему. Итак, я немного поискал, нашел эту настройку
cat /proc/sys/vm/overcommit_memory
0
Если я правильно понял, значение должно быть в порядке, и если процессу нужно больше ОЗУ, он сможет его получить.
Когда я делаю "верх", java-процесс - это процесс с максимальным использованием оперативной памяти.
top - 11:13:58 up 1 day, 4 min, 1 user, load average: 0.93, 0.94, 0.91
Tasks: 97 total, 1 running, 96 sleeping, 0 stopped, 0 zombie
Cpu(s): 11.2%us, 19.7%sy, 0.0%ni, 68.6%id, 0.0%wa, 0.0%hi, 0.5%si, 0.0%st
Mem: 3924136k total, 2736996k used, 1187140k free, 149380k buffers
Swap: 4128764k total, 0k used, 4128764k free, 814480k cached
PID USER PR NI VIRT RES SHR S %CPU %MEM TIME+ COMMAND
1486 root 20 0 3633m 1.5g 13m S 20.3 39.8 191:24.36 java
ОЗУ составляет около 4 ГБ, а файл SWAP такого же размера.
[root@atcrushftp ~]# cat /proc/meminfo
MemTotal: 3924136 kB
MemFree: 1159964 kB
Buffers: 149400 kB
Cached: 814476 kB
SwapCached: 0 kB
Active: 1956028 kB
Inactive: 619664 kB
Active(anon): 1611452 kB
Inactive(anon): 528 kB
Active(file): 344576 kB
Inactive(file): 619136 kB
Unevictable: 0 kB
Mlocked: 0 kB
SwapTotal: 4128764 kB
SwapFree: 4128764 kB
Dirty: 36 kB
Writeback: 4 kB
AnonPages: 1597696 kB
Mapped: 34108 kB
Shmem: 164 kB
Slab: 136024 kB
SReclaimable: 74432 kB
SUnreclaim: 61592 kB
KernelStack: 1384 kB
PageTables: 5948 kB
NFS_Unstable: 0 kB
Bounce: 0 kB
WritebackTmp: 0 kB
CommitLimit: 6090832 kB
Committed_AS: 746432 kB
VmallocTotal: 34359738367 kB
VmallocUsed: 285216 kB
VmallocChunk: 34359441520 kB
HardwareCorrupted: 0 kB
AnonHugePages: 1501184 kB
HugePages_Total: 0
HugePages_Free: 0
HugePages_Rsvd: 0
HugePages_Surp: 0
Hugepagesize: 2048 kB
DirectMap4k: 18432 kB
DirectMap2M: 4175872 kB
Я обратился в службу поддержки, но они говорят, что CrushFTP не виноват и в системе не хватает памяти.
Теперь у меня вопрос: как узнать, какой процесс занимает всю последнюю свободную память?
Прошло много времени с тех пор, как мне пришлось читать журнал OOM-убийцы, но, насколько я помню, это
Jun 28 05:06:23 crushftp kernel: Killed process 1491, UID 0, (java) total-vm:9620220kB, anon-rss:3245824kB, file-rss:128kB
означает, что Java использовала 9 ГБ виртуальной машины, когда убийца OOM выстрелил ей в голову. Учитывая, что у вас 4 ГБ ядра и 4 ГБ подкачки, это кажется разумным решением. Затем вы пишете
Если я правильно понял, значение должно быть в порядке, и если процессу нужно больше ОЗУ, он сможет его получить.
чего я не понимаю.
Во-первых, установив это значение на 0
не выключает чрезмерные обязательства. Как пишут в Red Hat, установив это в 0
требует, чтобы
ядро выполняет эвристическую обработку избыточного выделения памяти, оценивая объем доступной памяти и ошибочные запросы, которые являются явно недействительными. К сожалению, поскольку память выделяется с использованием эвристического, а не точного алгоритма, этот параметр иногда может допускать перегрузку доступной памяти в системе.
Установив его на 2
делает то, что вам кажется:
Ядро отклоняет запросы на память, равную или превышающую сумму общей доступной подкачки и процента физической RAM, указанной в overcommit_ratio. Этот параметр лучше всего подходит, если вы хотите снизить риск чрезмерного использования памяти.
Но даже отключение избыточной фиксации не гарантирует, что процесс всегда сможет получить больше оперативной памяти: это гарантирует только бесконечная виртуальная машина. Пока ядро + своп ограничен, его можно использовать - и если у вас есть процесс, который потреблял всю свободную виртуальную машину в тот момент, когда ядру нужно немного больше, тогда OOM-убийца проснется, и, ну, похоже, что и произошло.
Мои рекомендации:
Не беги java
как корень. В идеале вообще не запускайте его, но если нужно, то не от имени root; это придает ему вес в глазах OOM-убийц, что может привести к тому, что вместо этого будет убито что-то важное.
Найдите утечку памяти во всем, что использует java.
Если вы действительно считаете, что у вас нет утечки памяти, значит, у вас недостаточно ядра; Пони для большего сервера. Дайте ему больше обмена.
Лучше контролировать размер виртуальной машины Java; выстрелите ему в голову, если он весь опухнет.