无法在 AWS EC2 实例上分配可用内存(甚至一半!)

无法在 AWS EC2 实例上分配可用内存(甚至一半!)

我有两个略有不同的 AWS EC2 实例,它们属于同一类型,但内存容量巨大(c4.8xlarge60GB 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 

相关内容