duanjiebian6712 2018-06-08 14:10
浏览 85
已采纳

是什么导致malloc忽略交换空间?

I have setup a 4GB swapfile using dphys-swapfile additionally to the 1GB physical memory on a Raspberry Pi3 B+. The default was 100MB. I am running a go application, whose memory usage sometime peaks at about 1.2GB. However, even having 4GB swap memory, this peak causes an OOM error:

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

Why does malloc ignore the available swap space?

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

Setting vm.swappiness to 1, 10, 60, 100 or vm.overcommit_memory has no effect on this OOM.

My understanding was that OS would try to swap as much data as possible from the physical memory to avoid an OOM crash. But in this case it seems to just ignore it. What could be the reason?

ulimit values for completeness:

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条回答 默认 最新

  • doutan8601 2018-06-08 16:52
    关注

    You may be hitting memory fragmentation if you're running a 32-bit OS. It is very possible to reach a point where you can't even allocate a couple of megabytes because every possible virtual address is filled with something.

    This is especially bad with languages that use a lot of threads like Java, .NET or Go. Each thread gets its own stack which is placed somewhere that it can grow if it needs to.

    And combined with ASLR for security randomization, 32-bit memory gets fragmented very quickly.

    You could also be hitting the maximum map count. This even affects 64-bit systems but I haven't seen it happen with Go. Rust hits it a lot. Linux defaults this to 64k maps. I've increased it on my Linux systems:

    $ cat /etc/sysctl.d/20-max-maps.conf 
    vm.max_map_count = 262144
    
    本回答被题主选为最佳回答 , 对您是否有帮助呢?
    评论

报告相同问题?

悬赏问题

  • ¥20 sub地址DHCP问题
  • ¥15 delta降尺度计算的一些细节,有偿
  • ¥15 Arduino红外遥控代码有问题
  • ¥15 数值计算离散正交多项式
  • ¥30 数值计算均差系数编程
  • ¥15 redis-full-check比较 两个集群的数据出错
  • ¥15 Matlab编程问题
  • ¥15 训练的多模态特征融合模型准确度很低怎么办
  • ¥15 kylin启动报错log4j类冲突
  • ¥15 超声波模块测距控制点灯,灯的闪烁很不稳定,经过调试发现测的距离偏大