Linux - 内存、swap、内存回收机制

news/2024/12/21 18:15:40/

参考

2023年6月22日

  • https://zhuanlan.zhihu.com/p/107350459 —— 讨论的swap基于Linux4.4内核代码
  • 内存深度科普: 从堆内存到虚拟内存管理

2023年6月22日 qbittorrent swap 问题

  • https://github.com/qbittorrent/qBittorrent/issues/12947 massif valgrind --tool=massif qbittorrent
    • https://github.com/qbittorrent/qBittorrent/issues/12326#issuecomment-606296172 MTTuner
  • https://github.com/qbittorrent/qBittorrent/issues/11372

正文

内存

进程内存、用户系统空间(User Space Address)、系统虚拟内存(Virtual Memory)、物理内存(Physical Memory)

程序内存 ⇒ 物理内存

  • 在linux中,程序以进程形式运行,使用的内存称为“进程内存” —— 使用
  • “进程内存”由“用户系统空间”提供 —— 资源分配、权限管理
  • “用户系统空间”由“系统虚拟内存”提供 —— 系统管理(封装硬件调用,暴露调用接口)
  • “虚拟内存”通过“内存分页”映射到“物理内存”上 —— 物理to逻辑

在这里插入图片描述

在这里插入图片描述

在这里插入图片描述

读文件

处理器直接与内存交互、不直接与硬盘交互

如果内存没预先加载想要的硬盘数据,进程会进入中断,等待硬盘数据写入内存

程序逻辑地址、内存虚拟地址、硬盘物理地址

在这里插入图片描述

进程内存

进程(progress)内存(memory)使用有两种数据结构

  • Stack(栈) —— 大小已知的小资源
    • 方法调用
    • 本地变量存储
  • Heap(堆) —— 大小可变的大资源
    • 对象存储
    • callocmallocreallocfree —— 生成/释放一定大小的“块数据(block)”

在这里插入图片描述

在“进程”的内存空间中,堆和栈的内存空间相对生长。如果两者吃满,就会导致内存用尽,抛出OOM异常,进程终止。

在这里插入图片描述
在这里插入图片描述

所以,c语言的手动内存管理(manual heap allocation)写起来麻烦,写错了更麻烦。因此,在c以后的语言或多或少用“对象(Object)”、“类(Class)”的抽象概念替代堆、栈的具体概念,有意避免下游的开发者进行手动的堆栈内存管理,然后在语言编码层面封装了内存管理流程。
在这里插入图片描述
在这里插入图片描述

当然,这种自动管理内存的模式带来的弊端是“更多的程序执行步骤”,也就是(相对)更低的程序性能。
为了提高程序性能,如希望加快Android应用的响应速度,而Java部分无法再优化时,基于C/C++开发的NDK就会被选择 —— 开发者手动管理内存。

在这里插入图片描述

swap

Linux内存管理是一套非常复杂的系统,而swap只是其中一个很小的处理逻辑。

作用

  1. 内存扩展 —— “交换分区(swap)”主要是在内存不够用的时候,将部分内存上的数据交换到swap空间上,以便让系统不会因内存不够用而导致oom或者更致命的情况出现。
  2. 内存回收 —— 当进程不再需要某些内存数据时,这些将死、无用的进程的数据可以移动到swap分区中,从而释放物理内存空间。
  3. 系统休眠、恢复 —— 当系统需要休眠时,可以将内存中的数据保存在swap分区中,以便在唤醒后可以恢复到之前的状态。

swap分区一般设置为物理内存的1.5~2倍。
实际上,更具体的考虑,应该考虑实际的物理内存大小,实际的运行程序,硬盘类型来决定swap分区大小
e.g.

  • 小内存,大swap。大内存,swap不重要,但至少要是物理内存的一倍
  • nginx吃内存小、tomcat吃内存多、文件服务器 内存决定响应速度
  • 物理硬盘,往小了设置swap分区,确保程序不oom即可。

查看(挂载)

# see MOUNTPOINT
lsblk

查看(运行时)

查看个大概

$ htop

在这里插入图片描述

查看具体数值

$ freetotal        used        free      shared  buff/cache   available
Mem:        3856724     2281072      168644        1492     1407008     1315044
Swap:       4411308     1415572     2995736

查看分区

$ swapon -s
Filename                                Type            Size    Used    Priority
/dev/md1                                partition       2097084 63360   -1
/dev/zram0                              partition       578556  334768  1
/dev/zram1                              partition       578556  335844  1
/dev/zram2                              partition       578556  334904  1
/dev/zram3                              partition       578556  335864  1

创建(文件形式)

dd if=/dev/zero of=/swapfile bs=1G count=16
chmod 0600 /swapfile
格式化
mkswap /swapfile
# 挂载
swapon /swapfile
# 验证
free -h

创建(分区形式)

mkswap /dev/sdb4
swapon /dev/sdb4
free -h

swap策略

Linux有一个内核参数vm.swappiness,取值0-100,0表示不想用swap、100表示非常想用swap

e.g. pc,16g,swappiness=60,大约在6G(16G*40%=6.4G)的内存时候开始使用swap

$ cat /proc/sys/vm/swappiness
60
$ sysctl vm.swappiness # 查看
vm.swappiness = 60
$ vm.swappiness = 60 # 临时调整
$ echo 10 > /proc/sys/vm/swappiness # 临时调整
$ cat /etc/sysctl.conf | grep swap
vm.swappiness=10
$ sysctl -p # 激活

内存回收机制

内核(kernel)进行内存回收,原因主要有两个

  1. 内核需要为突发时刻到来的“内存申请”提供足够的“内存”,所以一般情况下需要保证有足够的free空间。
    当真的有大于空闲内存的申请到来的时候,会触发强制内存回收。
  2. 内核会使用内存中的page cache对部分文件进行缓存,以便提升文件的读写效率。
    但文件读写是随机的,所以可能大部分page cache长期不会被触发。
    所以内核有要设计一个周期性回收内存的机制,避免内存被长期占用。

所以,内核在应对这两类回收的需求下,分别实现了两种不同的机制

  1. 一个是使用kswapd进程对内存进行周期检查,以保证平常状态下剩余内存尽可能够用。
  2. 一个是直接内存回收(direct page reclaim),就是当内存分配时没有空闲内存可以满足要求时,触发直接内存回收

这两种内存回收的触发路径不同:

  1. 一个是由内核进程kswapd直接调用内存回收的逻辑进行内存回收;
    参见mm/vmscan.c中的kswapd()主逻辑
  2. 一个是内存申请的时候进入slow path的内存申请逻辑进行回收。
    参见内核代码中的mm/page_alloc.c中的__alloc_pages_slowpath方法

内存回收的方法、针对的对象

内存回收的两个过程在实际进行时殊途同归,最终都是调用shrink_zone()方法进行针对每个zone的内存页缩减。

这个方法中会再调用shrink_lruvec()(LRU,least recently used,最近最少使用)这个方法对每个"组织页"的链表进程检查。

这些链表主要定义在mm/vmscan.c一个enum中:

在这里插入图片描述

找到这个线索之后,我们就可以清晰的看到内存回收操作究竟针对的page有哪些了。

根据这个enum可以看到,内存回收主要需要进行扫描的链表有如下4个:

  • anoninactive
  • anonactive
  • fileinactive
  • fileactive

就是说,内存回收操作主要针对的就是内存中的文件页(file cache)和匿名页。

内存标记、内存回收流程

整个扫描的过程分几个循环:

  1. 首先扫描每个zone上的cgroup组;
  2. 然后再以cgroup的内存为单元进行page链表的扫描;
  3. 内核会先扫描anonactive链表(LRU_ACTIVE_ANON),将不频繁的放进inactive链表中(LRU_INACTIVE_ANON),然后扫描inactive链表,将里面活跃的移回active中;
    在这里插入图片描述

    关于活跃(active)还是不活跃(inactive)的判断内核会使用lru算法进行处理并进行标记,我们这里不详细解释这个过程。

  4. 进行swap的时候,先对inactive的页进行换出;
  5. 如果是file的文件映射page页(LRU_INACTIVE_FILE),则判断其是否为脏数据,如果是脏数据就写回,不是脏数据可以直接释放。

    脏数据:写入内存后,未同步

这样看来,内存回收这个行为会对两种内存的使用进行回收:

一种是anon的匿名页内存,主要回收手段是swap;

另一种是file-backed的文件映射页,主要的释放手段是写回和清空。

todo https://mp.weixin.qq.com/s?__biz=MzA4Nzg5Nzc5OA==&mid=2651660097&idx=1&sn=a3d38e3af2c9d8d431c46fe7680b428d&scene=2&srcid=0606f21oK1jm1IKMwEyi6aNz&from=timeline&isappinstalled=0#wechat_redirect


http://www.ppmy.cn/news/528814.html

相关文章

繁体批量转换工具:支持繁体字和简体本地化互转

繁体批量转换工具支持繁体字和简体字之间的互转和繁体字翻译成英文、德文、日文等多语种的翻译,并且在各语种之间来回互译,繁体批量转换工具可以对我们的网页内容、本地文件和多文本格式文档进行批量字体转换和语言翻译。 繁简体的转换更多的是出现在我们…

北通阿修罗2 Pro 多模板 连接Cemu 支持体感

需要使用体感的游戏基本上都是任天堂的游戏,如塞尔达。所以接下来针对CEMU模拟器介绍如何使用体感。 先看CEMU的手柄配置文档。 https://cemu.cfw.guide/controller-configuration.html 运动控制支持可能因手柄而异。任天堂Switch、Dualshock 4和DualSense手柄都支持…

简化字与繁体字的关系

简化字与繁体字的关系 根据《通用语言文字法》,教学用的是简化字。《纲要》要求硬笔书写要写简化字,但毛笔则要以经典碑帖为范本。我们现在见到和选用的可供临摹的碑帖,无一例外都是繁体字,有的还有异体字。因此,书法…

中国所有汉字-简体

一,丁,丂,七,丄,丅,丆,万,丈,三,上,下,丌,不,与,丏,丐,丑,丒,专,且,丕,世,丗,丘,丙,业,丛,东,丝,丞,丟,丠,両,丢,丣,两,严,並,丧,丨,丩,个,丫,丬,中,丮,丯,丰,丱,串,丳,临,丵,丶,丷,丸,丹,为,主,丼,丽,举,丿,乀,乁,乂,乃,乄,久,乆,乇,么,义,乊,之,乌,乍,乎,乏,乐,乑,乒,乓,乔,乕…

汉字简/繁体转换

<html><head><META http-equivContent-Type content"text/html; charsetGB2312"><title>汉字简体繁体转换</title></head><body><center><h3>汉字简体<u><b><font color"#FF0000"&g…

html简繁体转换,在线繁体字转换工具

输入简体字,点下面繁体字按钮进行在线转换【转】我不欠你的 -----这个故事觉得很有意义&#xff0c;转给大家看看。 有个美国小孩问他爸爸"我们很有钱吗?" 爸爸回答他 "我有钱&#xff0c;你没有。" 所以对孩子&#xff0c;要说人话。 去年暑假&#xff0…

繁简转换

package com.zf.tomcat;/*** 简体繁体转换器* author zhoufeng**/ public final class FJTransform {private final String simple "啊阿埃挨哎唉哀皑癌蔼矮艾碍爱隘鞍氨安俺按暗岸胺案肮昂盎凹敖熬翱袄傲奥懊澳芭捌扒叭吧笆八疤巴拔跋靶把耙坝霸罢爸白柏百摆佰败拜稗斑…

中文繁体与简体字转换

在Win10、Python3.6环境下&#xff0c;调用包&#xff0c;将繁体中文字转为简体字。 方法一&#xff1a; pip install snownlp 调用snownlp包进行转换。 from snownlp import SnowNLP s SnowNLP(環境很惡劣) s.han Out: 环境很恶劣 方法二&#xff1a; 下载 zh_wiki.p…