文档首页/ 弹性云服务器 ECS/ 故障排除/ 操作系统类(Linux)/ 如何处理Linux实例中的OOM问题?
更新时间:2025-09-17 GMT+08:00
分享

如何处理Linux实例中的OOM问题?

背景信息

OOM(Out of Memory)指系统内存已用完,在Linux系统中,如果内存用完会导致系统无法正常工作,触发系统panic或者OOM Killer。OOM Killer是Linux内核的一个机制,该机制会监控那些占用内存过大的进程,尤其是短时间内消耗大量内存的进程,在系统的内存即将不够用时结束这些进程从而保障系统的整体可用性。

问题现象

ECS实例在运行过程中日志中有类似于如下所示信息:

[  327.199955] 5202 total pagecache pages
[  327.200965] 0 pages in swap cache
[  327.201950] Swap cache stats: add 0, delete 0, find 0/0
[  327.203656] Free swap  = 0kB
[  327.204580] Total swap = 0kB
[  327.205491] 2096926 pages RAM
[  327.206375] 0 pages HighMem/MovableOnly
[  327.207509] 94837 pages reserved
[  327.208746] [ pid ]   uid  tgid total_vm      rss nr_ptes swapents oom_score_adj name
[  327.210727] [  352]     0   352     9764      616      22        0             0 systemd-journal
[  327.212897] [  372]     0   372    11370      150      23        0         -1000 systemd-udevd
[  327.214662] [  410]     0   410    13883      102      27        0         -1000 auditd
[  327.216276] [  498]    81   498    14558      164      33        0          -900 dbus-daemon
[  327.217880] [  499]     0   499     5385       62      16        0             0 irqbalance
[  327.219369] [  500]   999   500   153060     1350      63        0             0 polkitd
[  327.221158] [  502]     0   502   243884     3537      36        0             0 uniagent
[  327.222916] [  503]     0   503   137033     1033      84        0             0 NetworkManager
[  327.225002] [  505]     0   505     6596       77      19        0             0 systemd-logind
[  327.226841] [  508]   998   508    29452      105      30        0             0 chronyd
[  327.228427] [  529]     0   529    26123      488      21        0             0 uniagentd
[  327.230120] [  532]     0   532   143572     2883      96        0             0 tuned
[  327.231779] [  563]     0   563    25753      514      51        0             0 dhclient
[  327.233396] [  608]     0   608    54632      688      42        0             0 rsyslogd
[  327.235004] [  839]     0   839    39781      400      42        0             0 hostwatch
[  327.236505] [  904]     0   904   335577     1654     112        0             0 [kworker/0:0H]
[  327.237967] [ 1059]     0  1059    22452      253      45        0             0 master
[  327.239371] [ 1074]    89  1074    22478      250      44        0             0 pickup
[  327.240758] [ 1075]    89  1075    22495      252      45        0             0 qmgr
[  327.242087] [ 1416]     0  1416    28251      259      57        0         -1000 sshd
[  327.243474] [ 1418]     0  1418     6477       51      18        0             0 atd
[  327.244773] [ 1420]     0  1420    31597      152      18        0             0 crond
[  327.246133] [ 1422]     0  1422    24842      166      51        0             0 login
[  327.247893] [ 1423]     0  1423    27552       32      10        0             0 agetty
[  327.249319] [ 2359]     0  2359   197550     4903      48        0             0 containerserver
[  327.250828] [ 7726]     0  7726    63736      535      22        0             0 uniagentd
[  327.252278] [ 7727]     0  7727    98075      305      26        0             0 uniagentd
[  327.253688] [ 7773]     0  7773    28886      101      13        0             0 bash
[  327.254906] [ 7840]     0  7840   225333     3183      34        0             0 telescope
[  327.256240] [ 7922]     0  7922    39390      374      83        0             0 sshd
[  327.257496] [ 7924]     0  7924    28887      102      13        0             0 bash
[  327.258769] [ 7943]     0  7943    18088      190      39        0             0 sftp-server
[  327.260041] [ 8076]     0  8076  1958387  1904796    3739        0             0 python3
[  327.261301] Out of memory: Kill process 8076 (python3) score 924 or sacrifice child
[  327.262504] Killed process 8076 (python3), UID 0, total-vm:7833548kB, anon-rss:7619112kB, file-rss:72kB, shmem-rss:0kB

可能原因

如果您在Linux实例上运行程序时,频繁发生OOM,可能是以下原因。

  • Linux实例的配置过低,无法满足程序运行所需的内存资源,引发OOM。
  • 应用程序代码对内存的使用不当,引发OOM。

处理方法

关于OOM的问题,请参考以下步骤进行处理:

  1. 执行以下命令,查看OOM相关日志。
    sudo less /var/log/messages    # CentOS 
    sudo less /var/log/syslog      # Ubuntu

    在日志中通过oom或者kill作为关键字进行搜索,以查看OOM问题的相关日志信息。

    日志中会存在OOM Killer评估进程时的标准输出标题行如下图,其中可通过对rss列(单位4KB)进行排序,查看内存消耗最大的进程。

    如果是业务进程占用的内存高导致的内存OOM,建议您可以进一步通过业务应用日志定位内存占用高的原因。

  2. 根据您排查的结果,可以选择对应的处理方案。

    问题原因

    处理建议

    Linux实例的配置过低,无法满足程序运行所需的内存资源。

    升级实例内存配置:变更ECS规格

    注意:

    更改实例规格的过程中,您需要停止并重新启动ECS实例,建议您在非业务高峰期时执行该操作,减少对您业务造成的影响。

    应用程序代码对内存的使用不当。

    优化应用程序代码,如对批量查询请求进行分页等。

参考信息

  1. OOM Killer评估进程时的标准输出标题行,各列具体详解如表1 OOM Killer评估进程时的标准输出标题行所示。
    表1 OOM Killer评估进程时的标准输出标题行

    列名

    全称

    含义解释

    pid

    Process ID

    进程的操作系统内部ID。

    uid

    User ID

    启动该进程的用户ID。0代表root用户。

    tgid

    Thread Group ID

    线程组ID。

    • 对于单线程进程,这与pid相同。
    • 对于多线程程序,所有线程共享同一个tgid。

    total_vm

    Total Virtual Memory

    进程占用的总虚拟内存大小(以4KB的页为单位)。这个值很大,因为它包括共享库、映射的文件等,不是衡量内存压力的最佳指标。

    rss

    Resident Set Size

    驻留集大小(以4KB的页为单位)。这是进程当前在物理内存中占用的、非交换的内存总量。这是 OOM Killer 最重要的考量因素之一,它直接反映了进程对物理内存的消耗。

    nr_ptes

    Number of Page Table Entries

    页表项数目。进程使用的虚拟内存越多,需要的页表项就越多。这项本身也消耗内存,所以也是 OOM 评分的一个因素。

    swapents

    Swap Entries

    被换出到交换分区(Swap)的内存大小(以4KB的页为单位)。值越高,说明该进程的一些内存当前不在物理RAM中。

    oom_score_adj

    OOM Score Adjust

    OOM调整值(范围从-1000到1000)。这是用户态可以设置的最重要的参数,用于主动影响 OOM Killer的决策。

    name

    Process Name

    进程的可执行文件名称。

  2. OOM相关参数如表2 OOM相关参数表所示。
    表2 OOM相关参数表

    参数名称

    参数说明

    取值

    修改方式

    panic_on_oom

    panic_on_oom参数是控制系统遇到OOM时如何反应的。当系统遇到OOM的时候,通常会有两种选择:

    • 触发系统panic,可能会出现频繁宕机的情况。
    • 选择一个或者几个进程,触发OOM Killer,结束选中的进程,释放内存,让系统保持整体可用。

    可以通过以下命令查看参数取值:

    cat /proc/sys/vm/panic_on_oom或者

    sysctl -a | grep panic_on_oom

    • 值为0:内存不足时,触发OOM Killer。
    • 值为1:内存不足时,根据具体情况可能发生kernel panic,也可能触发OOM Killer。
    • 值为2:内存不足时,强制触发系统panic,导致系统重启。

    例如:将参数设置为0,可用以下两种方式:

    • 临时配置,立即生效,但重启后恢复成默认值。

      sysctl -w vm.panic_on_oom=0

    • 持久化配置,系统重启仍生效。

      执行命令vim /etc/sysctl.conf,在该文件中添加一行vm.panic_on_oom =0,再执行命令sysctl –p或重启系统后生效。

    oom_kill_allocating_task

    当系统选择触发OOM Killer,试图结束某些进程时,oom_kill_allocating_task参数会控制选择哪些进程,有以下两种选择:

    • 触发OOM的进程。
    • oom_score得分最高的进程。

    可以通过以下命令查看参数取值:

    cat /proc/sys/vm/oom_kill_allocating_task或者sysctl -a | grep oom_kill_allocating_task

    • 值为0:选择oom_score得分最高的进程。
    • 值为非0:选择触发OOM的进程。

    例如:将该参数设置成1,可用以下两种方式:

    • 临时配置,立即生效,但重启后恢复成默认值。

      sysctl -w vm.oom_kill_allocating_task=1

    • 持久化配置,系统重启仍生效。

      执行命令vim /etc/sysctl.conf,在该文件中添加一行vm.oom_kill_allocating_task=1,再执行命令sysctl –p或重启系统后生效。

    oom_score

    指进程的得分,主要有两部分组成:

    • 系统打分,主要是根据该进程的内存使用情况由系统自动计算。
    • 用户打分,也就是oom_score_adj,可以自定义。

    可以通过调整oom_score_adj的值进而调整一个进程最终的得分。通过以下命令查看参数取值:

    cat /proc/进程id/oom_score_adj

    • 值为0:不调整oom_score。
    • 值为负值:在实际打分值上减去一个折扣。
    • 值为正值:增加该进程的oom_score。

    例如:将进程id为2939的进程oom_score_adj参数值设置为1000,可用以下命令:

    echo 1000 > /proc/2939/oom_score_adj

    oom_dump_tasks

    oom_dump_tasks参数控制OOM发生时是否记录系统的进程信息和OOM Killer信息。

    例如dump系统中所有的用户空间进程关于内存方面的一些信息,包括:进程标识信息、该进程使用的内存信息、该进程的页表信息等,这些信息有助于了解出现OOM的原因。

    可以通过以下命令查看参数取值:

    cat /proc/sys/vm/oom_dump_tasks或者sysctl -a | grep oom_dump_tasks

    • 值为0:OOM发生时不会打印相关信息。
    • 值为非0:以下三种情况会调用dump_tasks打印系统中所有task的内存状况。
      • 由于OOM导致kernel panic。
      • 没有找到需要结束的进程。
      • 找到进程并将其结束的时候。

    例如:将该参数设置成0,可用以下两种方式:

    • 临时配置,立即生效,但重启后恢复成默认值。

      sysctl –w vm.oom_dump_tasks=0

    • 持久化配置,系统重启仍生效。

      执行命令vim /etc/sysctl.conf,在该文件中添加一行vm.oom_dump_tasks=0,再执行命令sysctl –p或重启系统后生效。

相关文档