【Linux内核】内存管理——内存回收机制

这篇具有很好参考价值的文章主要介绍了【Linux内核】内存管理——内存回收机制。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

转载请注明: https://www.cnblogs.com/Ethan-Code/p/16626560.html

内存回收的方式

前文提到malloc的内存分配方式,malloc申请的是虚拟内存,只有在程序去访问时,才会触发缺页异常进入内核态,在缺页中断函数中建立物理内存映射。

如果物理内存充足,则直接建立页框与页的映射。当物理内存不足时,内核会进行物理内存回收,内存回收的方式主要有:

  1. 后台内存回收(kswapd)
  2. 直接内存回收(direct reclaim)
  3. OOM机制(Out of Memory)

三种内存回收方式按内存的紧缺程度递进。

【Linux内核】内存管理——内存回收机制

后台内存回收——kswapd

本小节提到的内存主要针对物理内存

kswapd 是一个内核线程,在内存不足时负责在后台进行内存回收,这个过程发生在后台,因此是异步发生,不会阻塞进程。

内核对的容量设置了三个阈值:

  • 页最小阈值(pages_min);
  • 页低阈值(pages_low);
  • 页高阈值(pages_high);
【Linux内核】内存管理——内存回收机制

当内存大于 pages_low 时,表示此时系统内存足够,不会进行内存回收。

当内存小于 pages_low 时,表示此时内存存在压力,会触发 kswapd0 进行后台内存回收,直到 pages_high 为止

当内存小于 pages_min 时,表示此时用户内存耗尽,会触发直接内存回收,进程被阻塞。

如果要调整 kswapd 的触发时机,需要修改 pages_low 的值,而**pages_low的值由pages_min计算,因此需要修改pages_min**。

内核选项 /proc/sys/vm/min_free_kbytes 可以设置 pages_min

因此可以通过 min_free_kbytes 的值来修改内存水位阈值。

直接内存回收

在进程申请并访问内存时,如果此时内存可用page数小于pages_min,不足以进行内存分配建立映射关系。

此时会触发直接内存回收,阻塞进程的同时开始回收内存,因此这种内存回收方式是同步的。

对进程的阻塞会造成长时间的延迟,系统CPU利用率会升高,系统负荷会增大,因此要尽量避免直接内存回收。

OOM——Out of Memory

如果直接内存回收之后,系统的剩余空闲内存还不足以进行内存分配,则会进一步触发OOM机制。

OOM Killer 机制会根据算法选择并kill掉一个占用物理内存较高的进程,以便释放内存资源,如果物理内存依然不足,OOM Killer 会继续杀死占用物理内存较高的进程,直到释放足够的内存位置。

Linux 内核里有一个 oom_badness() 函数,它会把系统中可以被杀掉的进程扫描一遍,并对每个进程打分,得分最高的进程就会被首先杀掉。

进程的得分一般由其占用的物理内存页框数量决定。

函数 oom_badness() 计算方法:points = process_pages + oom_score_adj*totalpages/1000

变量 含义
points 打分的结果
process_pages 进程已经使用的物理内存页面数
oom_score_adj 进程的 OOM 校准值 一般为0
totalpages 系统总的可用页面数

可以通过设置 OOM校准值 即 修改 /proc/[pid]/oom_score_adj 的值来调整OOM,从而改变这个进程的得分结果,降低该进程被 OOM 杀死的概率。

oom_score_adj的设置范围是[-1000,1000]

内存回收时机的性能影响

sar -B 1 命令可以观察内存回收情况:

【Linux内核】内存管理——内存回收机制

pgscank/s : kswapd 每秒扫描的 page 个数
pgscand/s: 应用程序在内存申请过程中每秒直接扫描的 page 个数
pgsteal/s: 扫描的 page 中每秒被回收的个数(pgscank+pgscand)。

当 pages_low 设置不合理时,kswapd后台回收内存不及时,申请内存会经常触发直接内存回收,pgscand/s 数值会比较大,在性能上看会造成系统抖动。可以通过适当增大 min_free_kbytes,提前触发 kswapd 内核线程,避免直接内存回收。

修改 min_free_kbytes 的性能影响:

  • min_free_kbytes 比较小,系统预留较小的空闲内存,因此大部分内存都给进程使用。但是会导致kswapd回收不及时,触发直接内存回收,阻塞进程。
  • min_free_kbytes 比较大,系统则会预留更多空闲内存,在提升性能的同时会减少应用进程的可用内存,降低内存利用率,是空间换时间的方式。
  • min_free_kbytes 特别大,极端情况下接近总内存大小,只有很少的内存可以使用,可能会频繁触发OOM。

内存回收的具体过程——文件页和匿名页

上述提到的两种内存回收方式(kswapd和直接回收)主要回收的对象是内存中的文件页和匿名页。

  • 文件页(File-backed Page):内核缓存的磁盘数据(Buffer)和内核缓存的文件数据(Cache)都叫作文件页。
  • 匿名页(Anonymous Page):这部分内存没有实际载体,如堆、栈数据等,不像文件缓存有硬盘文件这样一个载体。

文件页和匿名页的回收都是基于LRU算法(最近最少使用算法)。

在Linux内核中LRU算法维护两条双向链表:active链表inactive链表,通过PG_active位状态判断是否活跃,通过PG_referenced位状态判断是否访问过。通过这两个页面标识符决定如何在两个链表之间移动页面。

实际上,对链表的并发访问需要使用自旋锁避免冲突,对此内核还提供了LRU缓存机制,只有当要插入到这两条链表的页面达到一定数量时才会一次性添加到相应链表中,从而降低锁的竞争,提升系统性能。

内存不足时,内核会优先回收 inactive链表 的尾部页面。

  • 文件页回收:如果这个文件页是干净的(clean),则直接释放内存,不影响系统性能。如果是脏页(dirty),则需要先写入磁盘,再释放内存,这个过程会发生IO操作,因此会影响系统性能。
  • 匿名页回收:因为这部分内存可能还会使用到,因此不能直接释放。如果开启了swap机制,则会先把内存存入磁盘中,等到需要的时候再从磁盘中读出。这个过程会发生IO操作,因此会影响系统性能。

可以看出,除了回收干净文件页,其他内存页回收基本都会发生磁盘IO,对系统的性能是会影响的。

因此,对于内存回收,应该设置根据需求设置合适的参数,从而调整kswapd的内存回收时机,调整直接内存回收的频率,减少OOM机制的触发,提高系统的性能和稳定性。


好文推荐:https://xiaolincoding.com/os/3_memory/mem_reclaim.html
关于LRU可以参考:https://www.cnblogs.com/muahao/p/10109712.html文章来源地址https://www.toymoban.com/news/detail-407221.html

到了这里,关于【Linux内核】内存管理——内存回收机制的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • Linux内核源码分析 (6)RCU机制及内存优化屏障

    问题: RCU 英文全称为 Read-Copy-Update ,顾名思义就是 读-拷贝-更新 ,是 Linux 内核中重要的同步机制。 Linux 内核已有原子操作、读写信号量等锁机制,为什么要单独设计一个比较复杂的新机制? RCU的原理 RCU记录所有指向共享数据的指针的使用者,当要修改该共享数据时,首先

    2024年02月10日
    浏览(46)
  • 深入理解Linux内核——内存管理(3)

    提要:本系列文章主要参考 MIT 6.828课程 以及两本书籍 《深入理解Linux内核》 《深入Linux内核架构》 对Linux内核内容进行总结。 内存管理的实现覆盖了多个领域: 内存中的物理内存页的管理 分配大块内存的伙伴系统 分配较小内存的slab、slub、slob分配器 分配非连续内存块的

    2024年02月13日
    浏览(33)
  • 深入理解Linux内核——内存管理(1)

    提要:本系列文章主要参考 MIT 6.828课程 以及两本书籍 《深入理解Linux内核》 《深入Linux内核架构》 对Linux内核内容进行总结。 内存管理的实现覆盖了多个领域: 内存中的物理内存页的管理 分配大块内存的伙伴系统 分配较小内存的slab、slub、slob分配器 分配非连续内存块的

    2024年02月13日
    浏览(30)
  • 深入理解Linux内核——内存管理(2)

    提要:本系列文章主要参考 MIT 6.828课程 以及两本书籍 《深入理解Linux内核》 《深入Linux内核架构》 对Linux内核内容进行总结。 内存管理的实现覆盖了多个领域: 内存中的物理内存页的管理 分配大块内存的伙伴系统 分配较小内存的slab、slub、slob分配器 分配非连续内存块的

    2024年02月13日
    浏览(33)
  • Linux内核组成分析【转载】

    Linux内核是Linux操作系统的核心部分,它是一个类Unix的操作系统内核,提供了必要的服务并管理系统资源。内核充当硬件和软件层之间的接口,使操作系统能够与底层硬件 组件进行通信和控制。以下是Linux内核的一些重要功能: 进程管理:内核管理进程的执行,分配CPU时间、

    2024年01月22日
    浏览(65)
  • 【嵌入式环境下linux内核及驱动学习笔记-(10-内核内存管理)】

    对于包含MMU(内存管理单元)的处理器而言,linux系统以虚拟内存的方式为每个进程分配最大4GB的内存。这真的4GB的内存空间被分为两个部分–用户空间 与 内核空间。用户空间地地址分布为0~3GB,剩下的3 ~ 4GB 为内核空间。如下图。 用户进程通常只能访问用户空间的虚拟地址

    2024年02月11日
    浏览(40)
  • 深入理解Linux内核——内存管理(4)——伙伴系统(1)

    提要:本系列文章主要参考 MIT 6.828课程 以及两本书籍 《深入理解Linux内核》 《深入Linux内核架构》 对Linux内核内容进行总结。 内存管理的实现覆盖了多个领域: 内存中的物理内存页的管理 分配大块内存的伙伴系统 分配较小内存的slab、slub、slob分配器 分配非连续内存块的

    2024年02月10日
    浏览(37)
  • 【Linux 内核源码分析】内存管理——Slab 分配器

    在Linux内核中,伙伴分配器是一种内存管理方式,以页为单位进行内存的管理和分配。但是在内核中,经常会面临结构体内存分配问题,而这些结构体的大小通常是小于一页的。如果使用伙伴分配器来分配这些小内存,将造成很大的内存浪费。因此,为了解决这个问题,Sun公

    2024年02月22日
    浏览(45)
  • Redis内存优化——内存淘汰及回收机制

    本文是系列文章,为了增强您的阅读体验,已将系列文章目录放入文章末尾。👍👍👍 Redis内存淘汰及回收策略都是Redis 内存优化兜底 的策略,那它们是如何进行 兜底 的呢?先来说明一下什么是内存淘汰和内存回收策略: Redis内存淘汰:当Redis的内存使用 超过配置 的限制时

    2024年02月08日
    浏览(28)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包