Назад | Перейти на главную страницу

CentOS, ядро: недостаточно памяти

Надеюсь, вы поможете мне со следующей проблемой.

Мы запускаем службу 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-убийца проснется, и, ну, похоже, что и произошло.

Мои рекомендации:

  1. Не беги java как корень. В идеале вообще не запускайте его, но если нужно, то не от имени root; это придает ему вес в глазах OOM-убийц, что может привести к тому, что вместо этого будет убито что-то важное.

  2. Найдите утечку памяти во всем, что использует java.

  3. Если вы действительно считаете, что у вас нет утечки памяти, значит, у вас недостаточно ядра; Пони для большего сервера. Дайте ему больше обмена.

  4. Лучше контролировать размер виртуальной машины Java; выстрелите ему в голову, если он весь опухнет.