我有两个略有不同的 AWS EC2 实例,它们属于同一类型,但内存容量巨大(c4.8xlarge
60GB RAM)。其中一个实例只是从备份映像 (AMI) 启动的副本,无法在其上重现该问题。
我停止了除系统服务之外的所有服务,因此大部分内存都是空闲的:
> free -m
total used free shared buff/cache available
Mem: 60382 201 59545 9 635 59695
Swap: 0 0 0
我无法分配甚至一半使用实用程序的可用内存stress
:
> sudo stress --vm 1 --vm-keep --vm-bytes 30G
stress: info: [40005] dispatching hogs: 0 cpu, 0 io, 1 vm, 0 hdd
stress: FAIL: [40006] (494) hogvm malloc failed: Cannot allocate memory
...
输出如下memtester
:
> sudo memtester 60000
memtester version 4.3.0 (64-bit)
Copyright (C) 2001-2012 Charles Cazabon.
Licensed under the GNU General Public License version 2 (only).
pagesize is 4096
pagesizemask is 0xfffffffffffff000
want 60000MB (62914560000 bytes)
got 29811MB (31259688960 bytes), trying mlock ...locked.
Loop 1:
Stuck Address : ok
...
没有ulimit
启用任何内存限制。我在该服务器的副本上遇到了同样的问题。但从旧映像恢复的服务器上一切正常:
> stress --vm 1 --vm-keep --vm-bytes 58G
stress: info: [14516] dispatching hogs: 0 cpu, 0 io, 1 vm, 0 hdd
> sudo memtester 59000
memtester version 4.3.0 (64-bit)
Copyright (C) 2001-2012 Charles Cazabon.
Licensed under the GNU General Public License version 2 (only).
pagesize is 4096
pagesizemask is 0xfffffffffffff000
want 59000MB (61865984000 bytes)
got 59000MB (61865984000 bytes), trying mlock ...locked.
...
我该怎么做才能解决这个问题?
答案1
看起来有人vm.overcommit_memory
在新图像中将值设置为 2。
https://www.kernel.org/doc/Documentation/vm/overcommit-accounting:
2 - Don't overcommit. The total address space commit
for the system is not permitted to exceed swap + a
configurable amount (default is 50%) of physical RAM.
Depending on the amount you use, in most situations
this means a process will not be killed while accessing
pages but will receive errors on memory allocation as
appropriate.
要解决该问题 - 启用 vm.overcommit_memory(将其设置为 0),或调整 vm.overcommit_ratio,或进行 30Gb 交换。
我真的不知道如何解决这些奇怪的问题,但我可能会做以下事情:
- 阅读所有与内存管理相关的内核文档。
- 比较
vm.*
两台服务器上的 sysctl 参数。 - 检查 dmesg 消息中是否存在硬件/系统错误。
- 使用调试信息构建内核,附加调试器,在 mmap 系统调用附近的某处设置断点并查看发生了什么。
答案2
另一个可能的原因是 Linux 内核的值vm.max_map_count
限制了您的应用。它设置了进程可以拥有的 mmap 数量的最大值,这可能会导致应用出现堆分配错误,例如:
fatal error: out of memory allocating heap arena metadata
使用以下方法读取当前值:
sudo sysctl vm.max_map_count
使用以下方法更新值:
# Double the value
sudo sysctl -w vm.max_map_count=131072
# Apply now during runtime
sudo sysctl -p