Что может заставить malloc игнорировать пространство подкачки? - PullRequest
0 голосов
/ 08 июня 2018

Я установил файл подкачки 4 ГБ, используя dphys-swapfile дополнительно к физической памяти 1 ГБ на Raspberry Pi3 B +.По умолчанию было 100 МБ.Я запускаю приложение go, чье использование памяти иногда достигает пика в 1.2GB.Однако даже при наличии 4 ГБ подкачки этот пик вызывает ошибку OOM:

runtime: out of memory: cannot allocate 137035776-byte block (1053458432 in use)
fatal error: out of memory

runtime stack:
runtime.throw(0x6a2e8e, 0xd)
        /usr/local/go/src/runtime/panic.go:616 +0x60
runtime.largeAlloc(0x82ab0fc, 0x101, 0x11160b60)
        /usr/local/go/src/runtime/malloc.go:828 +0xdc
runtime.mallocgc.func1()
        /usr/local/go/src/runtime/malloc.go:721 +0x38
runtime.systemstack(0x0)
        /usr/local/go/src/runtime/asm_arm.s:349 +0x80
runtime.mstart()
        /usr/local/go/src/runtime/proc.go:1175

Почему malloc игнорирует доступное пространство подкачки?

root@raspberrypi:~# sysctl vm.swappiness
vm.swappiness = 100
root@raspberrypi:~# sysctl vm.overcommit_memory
vm.overcommit_memory = 1
root@raspberrypi:~# free
              total        used        free      shared  buff/cache   available
Mem:         949452       36448      847880        1148       65124      862884
Swap:       4194300       30464     4163836
root@raspberrypi:~# cat /proc/meminfo
MemTotal:         949452 kB
MemFree:          847880 kB
MemAvailable:     862900 kB
Buffers:           10476 kB
Cached:            46848 kB
SwapCached:          872 kB
Active:            32140 kB
Inactive:          37728 kB
Active(anon):      10008 kB
Inactive(anon):     3692 kB
Active(file):      22132 kB
Inactive(file):    34036 kB
Unevictable:           0 kB
Mlocked:               0 kB
SwapTotal:       4194300 kB
SwapFree:        4163836 kB
Dirty:                20 kB
Writeback:             0 kB
AnonPages:         12072 kB
Mapped:            13024 kB
Shmem:              1148 kB
Slab:              18452 kB
SReclaimable:       7816 kB
SUnreclaim:        10636 kB
KernelStack:         888 kB
PageTables:         1140 kB
NFS_Unstable:          0 kB
Bounce:                0 kB
WritebackTmp:          0 kB
CommitLimit:     4669024 kB
Committed_AS:     114252 kB
VmallocTotal:    1114112 kB
VmallocUsed:           0 kB
VmallocChunk:          0 kB
CmaTotal:           8192 kB
CmaFree:            6780 kB

Установка vm.swappiness в 1, 10, 60, 100 или vm.overcommit_memory не влияет на это OOM.

Насколько я понимаю, ОС будет пытаться выгрузить как можно больше данных из физической памяти, чтобы избежать сбоя OOM.Но в этом случае, кажется, просто игнорировать это.В чем может быть причина?

Значения ulimit для полноты:

root@raspberrypi:~# ulimit -a
core file size          (blocks, -c) 0
data seg size           (kbytes, -d) unlimited
scheduling priority             (-e) 0
file size               (blocks, -f) unlimited
pending signals                 (-i) 7345
max locked memory       (kbytes, -l) 64
max memory size         (kbytes, -m) unlimited
open files                      (-n) 1024
pipe size            (512 bytes, -p) 8
POSIX message queues     (bytes, -q) 819200
real-time priority              (-r) 0
stack size              (kbytes, -s) 8192
cpu time               (seconds, -t) unlimited
max user processes              (-u) 7345
virtual memory          (kbytes, -v) unlimited
file locks                      (-x) unlimited

1 Ответ

0 голосов
/ 08 июня 2018

Возможно, вы столкнулись с фрагментацией памяти, если у вас 32-битная ОС.Очень возможно достичь точки, когда вы даже не можете выделить пару мегабайт, потому что каждый возможный виртуальный адрес заполнен чем-то.

Это особенно плохо с языками, которые используют много потоков, таких как Java,.NET или Go.Каждый поток получает свой собственный стек, который размещается где-то, где он может расти, если ему это необходимо.

И в сочетании с ASLR для рандомизации безопасности 32-битная память очень быстро фрагментируется.

Вы можететакже быть максимальным количеством карт.Это даже влияет на 64-битные системы, но я не видел, чтобы это случилось с Go.Ржавчина поражает это много.По умолчанию в Linux это 64k карт.Я увеличил его в моих системах Linux:

$ cat /etc/sysctl.d/20-max-maps.conf 
vm.max_map_count = 262144
...