阿里云-云小站(无限量代金券发放中)
【腾讯云】云服务器、云数据库、COS、CDN、短信等热卖云产品特惠抢购

操作系统的内存管理你知道吗

268次阅读
没有评论

共计 2395 个字符,预计需要花费 6 分钟才能阅读完成。

导读 brk() 的作用也只是通知 Linux 内核哪个范围的堆内存是可用的,真正的物理内存页是在进程实际读写内存的时候才会申请,而且是由内核根据写时复制 / 需求加载自动完成的,应用程序感知不到这点。

内存管理,是操作系统的主要功能。

操作系统从启动一直到创建 0 号进程(idle 进程),运行的大部分代码都跟内存有关。

操作系统的内存管理,大概分这么几个层次:

1. 物理内存管理

物理内存是电脑上的真实内存大小,这个数据可以通过 BIOS 获取。

在分页之后,物理内存的管理结构是个数组,每项表示 1 个物理内存页,每页 4096 字节。

如下图:

操作系统的内存管理你知道吗

物理内存的管理结构

在一个简单的内核 demo 里,物理内存页的管理结构可以只有一项:

atomic_t refs;

即,物理内存页的引用计数:计数为 0 表示空闲,> 0 表示正在使用,具体数字表示共享这一页的进程个数。

简单的内核 demo 一般是不支持 SMP 架构的,所以自旋锁(spinlock)也就省了。

在对称多处理器(SMP)的 CPU 上,因为全局数据结构会被多个 CPU 并发访问,所以要加自旋锁。

那么,物理内存页的管理结构至少有 2 项:

atomic_t spinlock;
atomic_t refs;

自旋锁的作用,与应用程序里的锁(mutex)差不多,只是它在获取失败之后会不断地再次获取,直到成功。

void spin_lock(atomic_t* lock)
{while (spin_trylock(lock) == 0);
}

这就是给自旋锁加锁的函数,while 循环直到成功,不成功时就自旋在那里一直转圈,所以叫自旋锁。

它在(对称多处理器)SMP 环境里用于保护共享的数据结构:当一个 CPU 持有自旋锁时,另一个 CPU 没法访问共享数据。

如果是单个 CPU 的环境,没必要用自旋锁,直接关闭中断就行了。

单个 CPU 的情况下,关了中断就可以阻止内核的并发,共享数据也就不会被踩踏了。

但多个 CPU 必须使用自旋锁,因为关中断只能关闭当前 CPU 的,没法关其他 CPU 的:这时需要自旋锁保护共享数据。

物理内存的管理数组,是最重要的全局共享数据。

当需要给一个进程申请内存的时候,哪个内存页是空闲的,哪个已经被使用了,全靠查看这个数组。

加自旋锁的时候一定要先关中断,因为如果在加了锁之后、关中断之前、正好有个中断来了,而在中断处理函数里再次请求加同一个锁,那就会递归死锁了。

Linux 内核的关中断加锁的函数叫:spin_lock_irqsave().

Linux 内核的分配物理内存页的函数叫:get_free_pages(),它可以分配 1 页或连续的多页内存。

如果分配多页内存的话,起始地址是要按页数对齐的。

2. 虚拟内存管理

虚拟内存都是通过进程的页表管理的。

为了节省物理内存,新创建的进程是与父进程共享同一套物理内存页的。

只有新进程要写某个内存页时,才会给它复制一份新的物理内存页,然后取消该页与父进程的共享,这就是写时复制。

操作系统的内存管理你知道吗

写时复制的过程

写时复制的过程:

1)申请一个新内存页,

2)把老内存页的内容,复制到新内存页上,

3)把新内存页的地址填入子进程的页表,

4)把老内存页的引用计数减 1。

所以,新进程刚被创建出来时,它的用户空间并没有自己的物理内存页,只有当运行需要时才一点点地通过写时复制添加,以让物理内存最大限度的空闲着。

另一个让物理内存最大限度空闲着的机制,就是需求加载:

1)当 mmap 一个文件时,操作系统并不会直接为这个文件分配内存,并且把它的内容加载到内存里,

2)而是当进程真去读这个文件的某一部分时,才给它申请物理内存页,并且把这一部分内容从磁盘读到内存。

copy on write,load on read.

不到火烧眉毛的时候,Linux 系统是不会把物理内存给进程的​

3. 用户态的内存函数

以上的这些机制都是 OS 内核里的,应用程序的代码不需要管这些。

应用程序分配内存的最底层函数,就是 brk() 系统调用。

操作系统的内存管理你知道吗

brk() 是一个系统调用,它的作用就是修改应用程序的数据段的结尾,从而分配或回收应用程序的堆空间。

操作系统的内存管理你知道吗

C 库里的把它封装成了 sbrk() 和 brk() 两个函数,让它使用起来更符合人们的习惯:

sbrk() 用于申请内存:void* sbrk(int increment);

brk() 用于回收内存:int brk(void* addr);

实际上,Linux 系统只有 1 个 brk() 系统调用,它既设置进程数据段的末尾,又会把这个值返回给应用程序。

操作系统的内存管理你知道吗

Linux 内核的头文件里,brk() 系统调用的处理函数 sys_brk() 是这么定义的,如上图。

如果想直接使用系统调用,可以使用 Linux 的 syscall() 函数,依次传入调用号和参数列表,就可以看到哪些是真实的系统调用,哪些是 C 库的封装。

syscall() 函数的声明是:long syscall(long number, …);

它的参数是可变的,系统调用的参数最多只有 6 个,因为寄存器的个数有限。

在 sbrk() 和 brk() 的基础上再封装,就是人们经常使用的 malloc() 和 free() 了。

malloc() 申请的内存是一块块的,可以不按次序释放,而不影响使用。

brk() 和 sbrk() 申请的内存必须按次序释放,因为它会修改进程的数据段结尾:

数据段结尾(brk)之外的堆空间如果被使用,就属于段错误。

所以,Linux man 手册里说明了,应用程序不要用 sbrk() 和 brk() 申请和释放内存。

brk() 的作用也只是通知 Linux 内核哪个范围的堆内存是可用的,真正的物理内存页是在进程实际读写内存的时候才会申请,而且是由内核根据写时复制 / 需求加载自动完成的,应用程序感知不到这点。

Linux 还会把不常用的物理内存页交换到磁盘上(即 swap 分区),以腾出更多的内存。

所以,在内存不足时,磁盘的读写频次也会升高。

阿里云 2 核 2G 服务器 3M 带宽 61 元 1 年,有高配

腾讯云新客低至 82 元 / 年,老客户 99 元 / 年

代金券:在阿里云专用满减优惠券

正文完
星哥玩云-微信公众号
post-qrcode
 0
星锅
版权声明:本站原创文章,由 星锅 于2024-07-24发表,共计2395字。
转载说明:除特殊说明外本站文章皆由CC-4.0协议发布,转载请注明出处。
【腾讯云】推广者专属福利,新客户无门槛领取总价值高达2860元代金券,每种代金券限量500张,先到先得。
阿里云-最新活动爆款每日限量供应
评论(没有评论)
验证码
【腾讯云】云服务器、云数据库、COS、CDN、短信等云产品特惠热卖中

星哥玩云

星哥玩云
星哥玩云
分享互联网知识
用户数
4
文章数
19351
评论数
4
阅读量
7974925
文章搜索
热门文章
星哥带你玩飞牛NAS-6:抖音视频同步工具,视频下载自动下载保存

星哥带你玩飞牛NAS-6:抖音视频同步工具,视频下载自动下载保存

星哥带你玩飞牛 NAS-6:抖音视频同步工具,视频下载自动下载保存 前言 各位玩 NAS 的朋友好,我是星哥!...
星哥带你玩飞牛NAS-3:安装飞牛NAS后的很有必要的操作

星哥带你玩飞牛NAS-3:安装飞牛NAS后的很有必要的操作

星哥带你玩飞牛 NAS-3:安装飞牛 NAS 后的很有必要的操作 前言 如果你已经有了飞牛 NAS 系统,之前...
我把用了20年的360安全卫士卸载了

我把用了20年的360安全卫士卸载了

我把用了 20 年的 360 安全卫士卸载了 是的,正如标题你看到的。 原因 偷摸安装自家的软件 莫名其妙安装...
再见zabbix!轻量级自建服务器监控神器在Linux 的完整部署指南

再见zabbix!轻量级自建服务器监控神器在Linux 的完整部署指南

再见 zabbix!轻量级自建服务器监控神器在 Linux 的完整部署指南 在日常运维中,服务器监控是绕不开的...
飞牛NAS中安装Navidrome音乐文件中文标签乱码问题解决、安装FntermX终端

飞牛NAS中安装Navidrome音乐文件中文标签乱码问题解决、安装FntermX终端

飞牛 NAS 中安装 Navidrome 音乐文件中文标签乱码问题解决、安装 FntermX 终端 问题背景 ...
阿里云CDN
阿里云CDN-提高用户访问的响应速度和成功率
随机文章
星哥带你玩飞牛NAS-16:飞牛云NAS换桌面,fndesk图标管理神器上线!

星哥带你玩飞牛NAS-16:飞牛云NAS换桌面,fndesk图标管理神器上线!

  星哥带你玩飞牛 NAS-16:飞牛云 NAS 换桌面,fndesk 图标管理神器上线! 引言 哈...
国产开源公众号AI知识库 Agent:突破未认证号限制,一键搞定自动回复,重构运营效率

国产开源公众号AI知识库 Agent:突破未认证号限制,一键搞定自动回复,重构运营效率

国产开源公众号 AI 知识库 Agent:突破未认证号限制,一键搞定自动回复,重构运营效率 大家好,我是星哥,...
安装并使用谷歌AI编程工具Antigravity(亲测有效)

安装并使用谷歌AI编程工具Antigravity(亲测有效)

  安装并使用谷歌 AI 编程工具 Antigravity(亲测有效) 引言 Antigravity...
星哥带你玩飞牛NAS-1:安装飞牛NAS

星哥带你玩飞牛NAS-1:安装飞牛NAS

星哥带你玩飞牛 NAS-1:安装飞牛 NAS 前言 在家庭和小型工作室场景中,NAS(Network Atta...
自己手撸一个AI智能体—跟创业大佬对话

自己手撸一个AI智能体—跟创业大佬对话

自己手撸一个 AI 智能体 — 跟创业大佬对话 前言 智能体(Agent)已经成为创业者和技术人绕...

免费图片视频管理工具让灵感库告别混乱

一言一句话
-「
手气不错
一句话生成拓扑图!AI+Draw.io 封神开源组合,工具让你的效率爆炸

一句话生成拓扑图!AI+Draw.io 封神开源组合,工具让你的效率爆炸

一句话生成拓扑图!AI+Draw.io 封神开源组合,工具让你的效率爆炸 前言 作为天天跟架构图、拓扑图死磕的...
星哥带你玩飞牛NAS-14:解锁公网自由!Lucky功能工具安装使用保姆级教程

星哥带你玩飞牛NAS-14:解锁公网自由!Lucky功能工具安装使用保姆级教程

星哥带你玩飞牛 NAS-14:解锁公网自由!Lucky 功能工具安装使用保姆级教程 作为 NAS 玩家,咱们最...
国产开源公众号AI知识库 Agent:突破未认证号限制,一键搞定自动回复,重构运营效率

国产开源公众号AI知识库 Agent:突破未认证号限制,一键搞定自动回复,重构运营效率

国产开源公众号 AI 知识库 Agent:突破未认证号限制,一键搞定自动回复,重构运营效率 大家好,我是星哥,...
还在找免费服务器?无广告免费主机,新手也能轻松上手!

还在找免费服务器?无广告免费主机,新手也能轻松上手!

还在找免费服务器?无广告免费主机,新手也能轻松上手! 前言 对于个人开发者、建站新手或是想搭建测试站点的从业者...
星哥带你玩飞牛NAS-11:咪咕视频订阅部署全攻略

星哥带你玩飞牛NAS-11:咪咕视频订阅部署全攻略

星哥带你玩飞牛 NAS-11:咪咕视频订阅部署全攻略 前言 在家庭影音系统里,NAS 不仅是存储中心,更是内容...