适用于:✔️ Linux VM
原始 KB 数: 4010058
本文讨论了运行 Linux 操作系统(OS)的Microsoft Azure 虚拟机(VM)耗尽内存(OOM)的几种方案。 OOM 条件会导致新的内存分配请求失败,或者导致 调用 OOM 终止程序 进程。 如果配置为执行此操作,则 内核会崩溃,并创建内存转储文件。
现象
在 Linux OS 中,运行 OS 时,随时可能会出现内存分配问题。 这些问题涉及不同的日志记录方案。 以下部分包含一些常见错误消息的示例。
症状 1:内存分配失败
[12345.678901] ruby: page allocation failure: order:0, mode:0x1080020(GFP_ATOMIC), nodemask=(null)
症状 2:内存不足
在与 OS 交互时,日志或命令行中遇到 OOM 错误。 例如,系统日志文件显示以下错误:
localhost kernel: Out of memory: Kill process 2154 (oom) score 844 or sacrifice child
以下文本显示了另一种形式的 OOM 消息。 此消息指示调用了 OOM 杀手:
Jul 7 21:09:50 hostname kernel: [ 1347.090377] output.rb:140 invoked oom-killer: gfp_mask=0x100cca(GFP_HIGHUSER_MOVABLE), order=0, oom_score_adj=0
在串行控制台或系统日志中,通常会为任何 OOM 事件生成内核堆栈跟踪。 该消息类似于以下文本:
[1774674.375021] out_of_memory+0x1ab/0x4a0
症状 3:分叉失败
如果 OS 尝试启动新进程但无法创建该进程,则会发生“无法分叉”消息。 此错误消息通常指示无法分叉进程的原因。 这种情况的一个常见原因是无法为初始进程状态分配必要的内存。 以下文本包含邮件的一种形式:
Feb 29 08:35:52 hostname systemd: Failed to fork: Cannot allocate memory
原因
在最高级别,此错误的基本原因是 OS 无法为发出的请求分配内存。 错误的原因可能有所不同,系统管理员必须在遇到错误时进行诊断。 内存分配失败的可能原因包括但不限于以下情况:
- 应用程序负载出现意外或非预期高峰或增长
- 内存碎片(小的可用内存块可用,但块都不够大,无法满足请求)
- 内存参数配置错误
- 应用程序存在内存泄漏
- 内核错误
- 缺少可用交换空间或完全交换
诊断
必须在发现错误时进行内存诊断。 诊断通常无法追溯进行。 可以使用各种工具和方法来诊断内存使用情况和碎片。 不应将以下工具列表视为包罗万象,但该列表是进行诊断的起点:
free
vmstat
top
htop
atop
cat /proc/meminfo
cat /proc/buddyinfo
echo m > /proc/sysrq-trigger
注意
此命令的输出位于系统日志中。 通常,此日志是 /var/log/messages 或 /var/log/syslog 文件。
sa/sar
注意
可以使用
sa
工具包以整体方式分析系统的历史聚合数据,但无需过程级详细信息。
解决方案
最合适的解决方案需要全面分析内存使用情况、模式和配置。 此类解决方案包括以下一个或多个操作项:
- 纵向扩展 VM 内存
- 重新配置
cgroup
定义(如果使用限制) - 更改大型页面分配
- 配置交换空间
若要在 Azure 中配置交换空间,可以在遵循 Azure 最佳做法的两种常规方法之间进行选择。 这两种方法都需要包含资源磁盘的 VM 模型。
系统类型 | 方法说明 |
---|---|
使用 cloud-init 的系统 | 首选方法是使用 cloud-init 配置或每启动脚本。 |
不使用 cloud-init 但使用 Azure 代理的系统 | /etc/waagent.conf 文件中存在配置指令,用于在资源磁盘中创建可自定义大小的交换文件。 |
有关这些方法的详细信息,请参阅以下文章:
第三方信息免责声明
本文中提到的第三方产品由 Microsoft 以外的其他公司提供。 Microsoft 不对这些产品的性能或可靠性提供任何明示或暗示性担保。
联系我们寻求帮助
如果你有任何疑问或需要帮助,请创建支持请求或联系 Azure 社区支持。 你还可以将产品反馈提交到 Azure 反馈社区。