Linux 的 OOM Killer 机制分析

2023-12-19 08:40
文章标签 分析 linux 机制 killer oom

本文主要是介绍Linux 的 OOM Killer 机制分析,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

Linux 的 OOM Killer 机制分析

 

按需分配物理页面

  很多情况下,一个进程会申请一块很大的内存,但只是用到其中的一小部分。为了避免内存的浪费,在分配页面时,Linux 采用的是按需分配物理页面的方式。譬如说,某个进程调用malloc()申请了一块小内存,这时内核会分配一个虚拟页面,但这个页面不会映射到实际的物理页面。


  从图中可以看到,当程序首次访问这个虚拟页面时,会触发一个缺页异常 (page fault)。这时内核会分配一个物理页面,让虚拟页面映射到这个物理页面,同时更新进程的页表 (page table)。

 

Memory Overcommit

  这种按需分配物理页面的方式,可以大大节省物理内存的使用,但有时会导致 Memory Overcommit。所谓 Memory Overcommit,也就是说,所有进程使用的虚拟内存超过了系统的物理内存和交换空间的总和。默认情况下,Linux 是允许 Memory Overcommit 的。并且在大多数情况下,Memory Overcommit 也是安全的,因为很多进程只是申请了很多内存,但实际使用到的内存并不多。
  但万一很多进程都使用了申请来的大部分内存,就可能导致物理内存和交换空间不够用了,这时内核的 OOM Killer 就会出马,它会选择杀掉一个或多个进程,这样就能腾出一些内存给其它进程使用。
  在 Linux 中,可以通过内核参数vm.overcommit_memory去控制是否允许 overcommit:

  • 默认值是 0,在这种情况下,只允许轻微的 overcommit,而比较明显的 overcommit 将不被允许。
  • 如果设置为 1,表示总是允许 overcommit。
  • 如果设置为 2,则表示总是禁止 overcommit。也就是说,如果某个申请内存的操作将导致 overcommit,那么这个操作将不会得逞

  那么对内核来说,怎样才算 overcommit 呢?Linux 设定了一个阈值,叫做 CommitLimit,如果所有进程申请的总内存超过了 CommitLimit,那就算是 overcommit 了。在/proc/meminfo中可以看到 CommitLimit 的大小:

 

1

2

 

$ cat /proc/meminfo | grep CommitLimit

CommitLimit: 3829768 kB

 

  CommitLimit 的值是这样计算的:

 

1

 

CommitLimit = [swap size] + [RAM size] * vm.overcommit_ratio / 100

 

  其中的vm.overcommit_ratio也是内核参数,它的默认值是 50。

OOM Killer

  当物理内存和交换空间不够用时,OOM Killer 就会选择杀死进程,那么它是怎样知道要先杀死哪个进程呢?其实 Linux 的每个进程都有一个 oom_score (位于/proc/<pid>/oom_score),这个值越大,就越有可能被 OOM Killer 选中。oom_score 的值是由很多因素共同决定的,这里列举几个因素:

  • 如果进程消耗的内存越大,它的 oom_score 通常也会越大。
  • 如果进程运行了很长时间,并且消耗很多 CPU 时间,那么通常它的 oom_score 会偏小。
  • 如果进程以 superuser 的身份运行,那么它的 oom_score 也会偏小。

  如何才能尽量防止某个重要的进程被杀死呢?Linux 每个进程都有一个 oom_adj (位于/proc/<pid>/oom_adj),这个值的范围是 [-17, +15],进程的 oom_adj 会影响 oom_score 的计算,也就是说,我们可以通过调小进程的 oom_adj 从而降低进程的 oom_score。对于一些比较重要的进程,例如 MySQL,我们想尽量避免它被 OOM Killer 杀死,这时候就可以调低它的 oom_adj 的值,例如:

 

1

 

$ sudo echo -10 > /proc/$(pidof mysqld)/oom_adj

 

交换空间

  通常来说操作系统都会开启交换空间,那么交换空间有什么作用呢?

  • 允许系统将一些长期没有用到的物理页面换出到交换空间,这样就能节省物理内存的使用。
  • 当物理内存不够使用时,系统可以利用交换空间作为缓冲,防止一些进程因为内存不够而被 OOM Killer 杀死。

  vm.swppiness可以用来配置交换空间,取值范围是 [0, 100],在 Linux 3.5 之后,它有这些作用:

  • 设置为 0 表示禁止交换空间的使用,只有当系统 OOM 时才允许使用交换空间。
  • 设置为 1 不会禁止交换空间的使用,但系统会尽量不去使用交换空间。
  • 设置为 100 表示系统会很喜欢使用交换空间。

  交换空间是位于磁盘之上的,对操作系统来说,访问磁盘的速度远远慢于访问物理内存。所以我们希望,当物理内存足够使用时,系统能尽量不去使用交换空间,这样能降低页面换入换出的频率,因为频繁的页面换入换出操作会严重影响系统的性能。为了达到这种效果,我们可以把vm.swappiness设置为 1:

 

1

 

sudo echo 1 > /proc/sys/vm/swappiness

 

参考资料

  • Memory overcommitment
  • OOM relation to vm.swappiness=0 in new kernel
  • Best Practices for Configuring Optimal MySQL Memory Usage

#Network

这篇关于Linux 的 OOM Killer 机制分析的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/511560

相关文章

使用docker搭建嵌入式Linux开发环境

《使用docker搭建嵌入式Linux开发环境》本文主要介绍了使用docker搭建嵌入式Linux开发环境,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面... 目录1、前言2、安装docker3、编写容器管理脚本4、创建容器1、前言在日常开发全志、rk等不同

linux系统上安装JDK8全过程

《linux系统上安装JDK8全过程》文章介绍安装JDK的必要性及Linux下JDK8的安装步骤,包括卸载旧版本、下载解压、配置环境变量等,强调开发需JDK,运行可选JRE,现JDK已集成JRE... 目录为什么要安装jdk?1.查看linux系统是否有自带的jdk:2.下载jdk压缩包2.解压3.配置环境

Linux搭建ftp服务器的步骤

《Linux搭建ftp服务器的步骤》本文给大家分享Linux搭建ftp服务器的步骤,本文通过图文并茂的形式给大家介绍的非常详细,对大家的学习或工作具有一定的参考借鉴价值,需要的朋友参考下吧... 目录ftp搭建1:下载vsftpd工具2:下载客户端工具3:进入配置文件目录vsftpd.conf配置文件4:

基于Redis自动过期的流处理暂停机制

《基于Redis自动过期的流处理暂停机制》基于Redis自动过期的流处理暂停机制是一种高效、可靠且易于实现的解决方案,防止延时过大的数据影响实时处理自动恢复处理,以避免积压的数据影响实时性,下面就来详... 目录核心思路代码实现1. 初始化Redis连接和键前缀2. 接收数据时检查暂停状态3. 检测到延时过

Redis中哨兵机制和集群的区别及说明

《Redis中哨兵机制和集群的区别及说明》Redis哨兵通过主从复制实现高可用,适用于中小规模数据;集群采用分布式分片,支持动态扩展,适合大规模数据,哨兵管理简单但扩展性弱,集群性能更强但架构复杂,根... 目录一、架构设计与节点角色1. 哨兵机制(Sentinel)2. 集群(Cluster)二、数据分片

Linux实现查看某一端口是否开放

《Linux实现查看某一端口是否开放》文章介绍了三种检查端口6379是否开放的方法:通过lsof查看进程占用,用netstat区分TCP/UDP监听状态,以及用telnet测试远程连接可达性... 目录1、使用lsof 命令来查看端口是否开放2、使用netstat 命令来查看端口是否开放3、使用telnet

Linux系统管理与进程任务管理方式

《Linux系统管理与进程任务管理方式》本文系统讲解Linux管理核心技能,涵盖引导流程、服务控制(Systemd与GRUB2)、进程管理(前台/后台运行、工具使用)、计划任务(at/cron)及常用... 目录引言一、linux系统引导过程与服务控制1.1 系统引导的五个关键阶段1.2 GRUB2的进化优

Linux查询服务器 IP 地址的命令详解

《Linux查询服务器IP地址的命令详解》在服务器管理和网络运维中,快速准确地获取服务器的IP地址是一项基本但至关重要的技能,下面我们来看看Linux中查询服务器IP的相关命令使用吧... 目录一、hostname 命令:简单高效的 IP 查询工具命令详解实际应用技巧注意事项二、ip 命令:新一代网络配置全

linux安装、更新、卸载anaconda实践

《linux安装、更新、卸载anaconda实践》Anaconda是基于conda的科学计算环境,集成1400+包及依赖,安装需下载脚本、接受协议、设置路径、配置环境变量,更新与卸载通过conda命令... 目录随意找一个目录下载安装脚本检查许可证协议,ENTER就可以安装完毕之后激活anaconda安装更

Linux查询服务器系统版本号的多种方法

《Linux查询服务器系统版本号的多种方法》在Linux系统管理和维护工作中,了解当前操作系统的版本信息是最基础也是最重要的操作之一,系统版本不仅关系到软件兼容性、安全更新策略,还直接影响到故障排查和... 目录一、引言:系统版本查询的重要性二、基础命令解析:cat /etc/Centos-release详