服务器频繁报错:
[2352218.368085] Out of memory: Kill process 1462 (transaction-exp) score 834 or sacrifice child
[2352218.368850] Killed process 1462 (transaction-exp) total-vm:18307836kB, anon-rss:13871180kB, file-rss:316kB, shmem-rss:0kB
total-vm: total virtual memory. 进程使用的总的虚拟内存。
rss: resident set size. 驻留集大小。驻留集是指进程已装入内存的页面的集合。
anon-rss: anonymous rss. 匿名驻留集。比如malloc出来的就是匿名的。
file-rss: 映射到设备和文件上的内存页面。
shmem-rss: 大概是shared memory rss?
本文介绍了 Linux 内存不足 (OOM) 杀手以及如何找出它杀死特定进程的原因。它还提供了配置 OOM 杀手的方法,以更好地满足许多不同环境的需求。
关于 OOM 杀手
当支持数据库或应用程序服务器的服务器出现故障时,通常需要争相恢复和运行关键服务,尤其是当它是一个重要的生产系统时。在初步分类后尝试确定根本原因时,应用程序或数据库为何突然停止运行通常是个谜。在某些情况下,问题的根本原因可以追溯到内存不足的系统并杀死一个重要进程以保持运行。
Linux 内核根据系统上运行的应用程序的需求分配内存。由于许多应用程序预先分配了它们的内存并且通常不使用分配的内存,因此内核被设计为能够过度使用内存以提高内存使用效率。这种过度提交模型允许内核分配比它实际可用的内存更多的内存。如果一个进程实际使用了分配给它的内存,内核就会将这些资源提供给应用程序。当太多应用程序开始使用分配给它们的内存时,过度使用模型有时会出现问题,内核必须开始终止进程以保持运行。内核用于恢复系统内存的机制称为内存不足杀手或简称OOM杀手。
找出进程被杀死的原因
在对应用程序被 OOM 杀手杀死的问题进行故障排除时,有几条线索可能会阐明进程被杀死的方式和原因。在下面的例子中,我们将看看我们syslog是否能找到问题的根源。由于内存不足,该oracle进程被 OOM 杀手杀死。大写K的Killed表示进程被-9信号杀死,这通常是OOM杀手可能是罪魁祸首的好兆头。
grep -i kill /var/log/messages*
host kernel: Out of Memory: Killed process 2592 (oracle).
我们还可以检查系统上低内存和高内存使用的状态。需要注意的是,这些值是实时的,并且会根据系统工作负载而变化;因此,这些应该在内存压力发生之前经常观察。在进程被杀死后查看这些值不会很有洞察力,因此无法真正帮助调查 OOM 问题。
[root@test-sys1 ~]# free -lm
total used free shared buffers cached
Mem: 498 93 405 0 15 32
Low: 498 93 405
High: 0 0 0
-/+ buffers/cache: 44 453
Swap: 1023 0 1023
在这个测试虚拟机上,我们有 498 MB 的低可用内存。系统没有交换使用。-l开关显示高低内存统计数据,开关-m以兆字节为单位输出,以便于阅读。
[root@test-sys1 ~]# egrep 'High|Low' /proc/meminfo
HighTotal: 0 kB
HighFree: 0 kB
LowTotal: 510444 kB
LowFree: 414768 kB
[root@test-sys1 ~]# egrep 'High|Low' /proc/meminfo
HighTotal: 0 kB
HighFree: 0 kB
LowTotal: 510444 kB
LowFree: 414768 kB
/proc/memory通过专门检查和查看高值和低值可以获得相同的数据。但是,使用这种方法,我们不会从输出中获取交换信息,并且输出以千字节为单位。
低内存是内核可以直接物理访问的内存。高内存是内核没有直接物理地址的内存,因此必须通过虚拟地址进行映射。在较旧的 32 位系统上,由于内存映射到虚拟地址的方式,您会看到低内存和高内存。在 64 位平台上,不需要虚拟地址空间,所有系统内存都将显示为低内存。
虽然查看/proc/memory和使用该free命令有助于“立即”了解我们的内存使用情况,但有时我们希望查看更长时间内的内存使用情况。该vmstat命令对此非常有用。
在清单 1 的示例中,我们使用该vmstat命令每 45 秒查看一次资源 10 次。-S开关在表格中显示我们的数据,开关-M以兆字节显示输出,以便于阅读。如您所见,有些东西正在消耗我们的空闲内存,但在这个例子中我们还没有交换。
[root@localhost ~]# vmstat -SM 45 10
procs -----------memory-------- ---swap-- -----io-- --system-- ----cpu---------
r b swpd free buff cache si so bi bo in cs us sy id wa st
1 0 0 221 125 42 0 0 0 0 70 4 0 0 100 0 0
2 0 0 192 133 43 0 0 192 78 432 1809 1 15 81 2 0
2 1 0 85 161 43 0 0 624 418 1456 8407 7 73 0 21 0
0 0 0 65 168 43 0 0 158 237 648 5655 3 28 65 4 0
3 0 0 64 168 43 0 0 0 2 1115 13178 9 69 22 0 0
7 0 0 60 168 43 0 0 0 5 1319 15509 13 87 0 0 0
4 0 0 60 168 43 0 0 0 1 1387 15613 14 86 0 0 0
7 0 0 61 168 43 0 0 0 0 1375 15574 14 86 0 0 0
2 0 0 64 168 43 0 0 0 0 1355 15722 13 87 0 0 0
0 0 0 71 168 43 0 0 0 6 215 1895 1 8 91 0 0
[root@localhost ~]# vmstat -SM 45 10
procs -----------memory-------- ---swap-- -----io-- --system-- ----cpu---------
r b swpd free buff cache si so bi bo in cs us sy id wa st
1 0 0 221 125 42 0 0 0 0 70 4 0 0 100 0 0
2 0 0 192 133 43 0 0 192 78 432 1809 1 15 81 2 0
2 1 0 85 161 43 0 0 624 418 1456 8407 7 73 0 21 0
0 0 0 65 168 43 0 0 158 237 648 5655 3 28 65 4 0
3 0 0 64 168 43 0 0 0 2 1115 13178 9 69 22 0 0
7 0 0 60 168 43 0 0 0 5 1319 15509 13 87 0 0 0
4 0 0 60 168 43 0 0 0 1 1387 15613 14 86 0 0 0
7 0 0 61 168 43 0 0 0 0 1375 15574 14 86 0 0 0
2 0 0 64 168 43 0 0 0 0 1355 15722 13 87 0 0 0
0 0 0 71 168 43 0 0 0 6 215 1895 1 8 91 0 0
清单 1
vmstat可以使用以下命令将输出重定向到文件。我们甚至可以调整持续时间和次数,以便监控更长时间。在命令运行时,我们可以随时查看输出文件以查看结果。
在以下示例中,我们每 120 秒查看一次内存 1000 次。行&尾的 允许我们将其作为一个进程运行并重新获得我们的终端。
vmstat -SM 120 1000 > memoryusage.out &
作为参考,清单 2 显示了vmstat手册页中的一个部分,该部分提供了有关命令提供的输出的附加信息。这只是与内存相关的信息;该命令还提供有关磁盘 I/O 和 CPU 使用率的信息。
Memory
swpd: the amount of virtual memory used.
free: the amount of idle memory.
buff: the amount of memory used as buffers.
cache: the amount of memory used as cache.
inact: the amount of inactive memory. (-a option)
active: the amount of active memory. (-a option)
Swap
si: Amount of memory swapped in from disk (/s).
so: Amount of memory swapped to disk (/s).
Memory
swpd: the amount of virtual memory used.
free: the amount of idle memory.
buff: the amount of memory used as buffers.
cache: the amount of memory used as cache.
inact: the amount of inactive memory. (-a option)
active: the amount of active memory. (-a option)
Swap
si: Amount of memory swapped in from disk (/s).
so: Amount of memory swapped to disk (/s).
清单 2
还有许多其他工具可用于监控内存和系统性能,以调查此类问题。sar(System Activity Reporter) 和(Dynamic Tracing) 等工具dtrace对于收集有关一段时间内系统性能的特定数据非常有用。为了获得更高的可见性,dtrace稳定性和数据稳定性探测器甚至具有 OOM 条件触发器,如果内核由于 OOM 条件而终止进程,则会触发该触发器。有关dtrace并sar包含在本文的“另请参阅”部分的更多信息。
除了系统因工作负载而耗尽 RAM 和可用交换空间之外,还有几件事可能会导致 OOM 事件。由于系统上的工作负载类型,内核可能无法最佳地利用交换空间。使用mlock() 或 HugePages 的应用程序的内存在系统开始运行时物理内存不足时无法交换到磁盘。内核数据结构也可能占用太多空间,耗尽系统内存并导致 OOM 情况。许多基于 NUMA 架构的系统可能会遇到 OOM 情况,因为一个节点内存不足会触发内核中的 OOM,而其余节点中仍有大量内存。有关具有 NUMA 架构的机器上的 OOM 条件的更多信息,请参阅“另请参阅“本文的部分。
配置 OOM Killer
Linux 上的 OOM 杀手有几个配置选项,允许开发人员选择系统在遇到内存不足情况时将表现出的行为。这些设置和选择因系统在其上配置的环境和应用程序而异。
注意:建议在对重要的生产系统进行更改之前在开发环境中进行测试和调整。
在某些环境中,当系统运行单个关键任务时,在系统运行到 OOM 条件时重新启动可能是一种可行的选择,可以在无需管理员干预的情况下快速将系统恢复到运行状态。虽然不是最佳方法,但其背后的逻辑是,如果我们的应用程序由于被 OOM 杀手杀死而无法运行,那么如果应用程序在启动时与系统一起启动,则重新启动系统将恢复应用程序。如果应用程序由管理员手动启动,则此选项无益。
以下设置将导致系统崩溃并在内存不足的情况下重新启动。这些sysctl命令将实时设置它,并将设置附加到sysctl.conf将允许这些设置在重新启动后继续存在。Xfor是系统应该重新启动之前的kernel.panic秒数。应调整此设置以满足您的环境的需要。
sysctl vm.panic_on_oom=1
sysctl kernel.panic=X
echo "vm.panic_on_oom=1" >> /etc/sysctl.conf
echo "kernel.panic=X" >> /etc/sysctl.conf
sysctl vm.panic_on_oom=1
sysctl kernel.panic=X
echo "vm.panic_on_oom=1" >> /etc/sysctl.conf
echo "kernel.panic=X" >> /etc/sysctl.conf
我们还可以调整 OOM 杀手处理某些进程的 OOM 条件的方式。oracle以我们之前被杀死的进程 2592为例。如果我们想让我们的oracle进程不太可能被 OOM 杀手杀死,我们可以执行以下操作。
echo -15 > /proc/2592/oom_adj
通过执行以下操作,我们可以使 OOM 杀手更有可能杀死我们的oracle进程。
echo 10 > /proc/2592/oom_adj
如果我们想将我们的oracle进程从 OOM 杀手中排除,我们可以执行以下操作,这会将其完全从 OOM 杀手中排除。请务必注意,这可能会导致意外行为,具体取决于系统的资源和配置。如果内核无法杀死使用大量内存的进程,它将转移到其他可用进程。其中一些进程可能是重要的操作系统进程,最终可能导致系统宕机。
echo -17 > /proc/2592/oom_adj
我们可以为oom_adjfrom -16to设置有效范围+15,并且设置-17完全免除 OOM 杀手的进程。数字越高,如果系统遇到 OOM 条件,我们的进程就越有可能被选择终止。还可以查看的内容/proc/2592/oom_score以确定进程被 OOM 杀手杀死的可能性有多大。分数0表示我们的进程不受 OOM 杀手的影响。OOM 分数越高,进程在 OOM 条件下被杀死的可能性就越大。
可以使用以下命令完全禁用 OOM 杀手。不建议将这用于生产环境,因为如果确实出现内存不足的情况,则可能会出现意外行为,具体取决于可用的系统资源和配置。这种意外行为可能是从内核恐慌到挂起,具体取决于在 OOM 条件时内核可用的资源。
sysctl vm.overcommit_memory=2
echo "vm.overcommit_memory=2" >> /etc/sysctl.conf
sysctl vm.overcommit_memory=2
echo "vm.overcommit_memory=2" >> /etc/sysctl.conf
对于某些环境,这些配置选项不是最佳的,可能需要进一步调整和调整。根据系统上运行的应用程序的需要,为内核配置 HugePages 可以帮助解决 OOM 问题。
版权属于: 三三世界-百宝箱
本文链接: http://33f.net/linux/linux-Out-of-Memory-Killer.html
本文最后更新于2022年05月29日 ,已超过1410天没有更新,若内容或图片失效,请留言反馈。
本文允许转载,但请在转载时请以超链接或其它形式标明文章出处
@Doug Shume it's ok for me , you can post here.
zh.us.to 有效
kms.03k.org 有效
kms.chinancce.com
kms.shuax.com 有效
kms.dwhd.org 有效
kms.luody.info 有效
kms.digiboy.ir 有效
kms.lotro.cc 有效
www.zgbs.cc 有效
cy2617.jios.org 有效
@ 权限问题,试试sudo 再加命令。
你好提示Permission denied 怎么办啊