您当前的位置:首页 > 电脑百科 > 软件技术 > 操作系统 > linux

Linux内核:虚拟地址到物理地址,是什么时候开始映射

时间:2021-12-07 09:40:03  来源:  作者:深度Linux

内核空间 和用户空间申请的内存最终和buddy怎么交互?以及在页表映射上的区别?虚拟地址到物理地址,什么时候开始映射?

Buddy的问题

分配的力度太大 buddy算法把空闲页面分成1,2,4页,buddy算法会明确知道哪一页内存空闲还是被占用?

4k,8k,16k

无论是在应用还是内核,都需要申请很小的内存。

从buddy要到的内存,会进行slab切割。

slab原理:

比如在内核中申请8字节的内存,buddy分配4K,分成很多个小的8个字节,每个都是一个object。

slab,slub,slob 是slab机制的三种不同实现算法。

linux 会针对一些常规的小的内存申请,数据结构,会做slab申请。

cat /proc/slabinfo 可以看到内核空间小块内存的申请情况,也是slab分配的情况。

<num_objs>:每个slab一共可以分出多少个obj, <active_objs> :还可以分配多少个obj, < pagesperslab>:每个slab对应多少个pages, < objperslab>:每个slab可以分出多少个object, < objsize>:每个obj多大,

slab主要分为两类:

一、常用数据结构像 nfsd_drc, UDPv6,TCPv6 ,这些经常申请和释放的数据结构。比如,存在TCPv6的slab,之后申请 TCPv6 数据结构时,会通过这个slab来申请。

Linux内核:虚拟地址到物理地址,是什么时候开始映射

 

二、常规的小内存申请,做的slab。例如 kmalloc-32,kmalloc-64, kmalloc-96, kmalloc-128

Linux内核:虚拟地址到物理地址,是什么时候开始映射

 


Linux内核:虚拟地址到物理地址,是什么时候开始映射

 

注意,slab申请和分配的都是只针对内核空间,与用户空间申请分配内存无关。用户空间的malloc和free调用的是libc。

更多Linux内核视频教程文档资料免费领取后台私信【内核大礼包】自行获取。

Linux内核:虚拟地址到物理地址,是什么时候开始映射

 

slab和buddy的关系?
1、slab的内存来自于buddy。slab相当于二级管理器。
2、slab和buddy在算法上,级别是对等的。

两者都是内存分配器,buddy是把内存条分成多个Zone来管理分配,slab是把从buddy拿到的内存,进行管理分配。

同理,malloc 和free也不找buddy拿内存。 malloc 和free不是系统调用,只是c库中的函数。

mallopt

在C库中有一个api是mallopt,可以控制一系列的选项。

Linux内核:虚拟地址到物理地址,是什么时候开始映射

 

M_TRIM_THRESHOLD:控制c库把内存还给内核的阈值。
-1UL 代表最大的正整数。

此处代表应用程序把内存还给c库后,c库并不把内存还给内核。

<do your RT-thing>
程序在此处申请内存,都不需要再和内核交互了,此时程序的实时性比较高。

kmalloc vs. vmalloc/ioremap

内存空间: 内存+寄存器

register --> LDR/STR

所有内存空间的东西,CPU去访问,都要通过虚拟地址。 CPU --> virt --> mmu --> phys

cpu请求虚拟地址,mmu根据cpu请求的虚拟地址,查页表的物理地址。

buddy算法,管理这一页的使用情况。

两个虚拟地址可以映射到同一个物理地址。

Linux内核:虚拟地址到物理地址,是什么时候开始映射

 

页表 -> 数组,任何一个虚拟地址,都可以用地址的高20位,作为页表的行号去读对应的页表项。而第12位,是指页面内偏移。(由于一页是4K,2^12 足够描述)

kmalloc 和 vmalloc 申请的内存,有什么区别? 答:申请之后,是否还要去改页表。一般情况,kmalloc申请内存,不需要再去改页表。同一张页表,几个虚拟地址可以同时映射到同一个物理地址。

寄存器,通过ioremap往vmalloc区域,进行映射。然后改进程的虚拟地址页表。

总结:所有的页,最底层都是用buddy算法进行管理,用虚拟地址找物理地址。理解内存分配和映射的区别,无论是lowmem还是highmem 都可以被vmalloc拿走,也可能被用户拿走,只不过拿走之后,还要把虚拟地址往物理地址再映射一遍。但如果是被kmalloc拿走,一般指低端内存,就不需要再改进程的页表。因为这部分低端内存,已经做好了虚实映射。

	cat /proc/vmallocinfo |grep ioremap

可以看到寄存器中的哪个区域,被映射到哪个虚拟地址。

vmalloc区域主要用来,vmalloc申请的内存从这里找虚拟地址 和 寄存器的ioremap映射。

Linux内存分配的lazy行为

Linux总是以最lazy的方式,给应用程序分配内存。

Linux内核:虚拟地址到物理地址,是什么时候开始映射

 

malloc100M内存成功时,其实并没有真实拿到。只有当100M内存中的任何一页,被写一次的时候,才成功。vss:虚拟地址空间。 rss:常驻内存空间malloc 100M内存成功时,Linux把100M内存全部以只读的形式,映射到一个全部清0的页面。

当应用程序写100M中每一页任意字节时,会发出page fault。 linux 内核收到缺页中断后,从硬件寄存器中读取到,包括缺页中断发生的原因和虚拟地址。Linux从内存条申请一页内存,执行cow,把页面重新拷贝到新申请的页表,再把进程页表中的虚拟地址,指向一个新的物理地址,权限也被改成R+W。

调用brk 把8k变成 16k。

针对应用程序的堆、代码、栈、等,会使用lazy分配机制,只有当写内存页时,才会真实请求内存分配页表。但,当内核使用kmalloc申请内存时,就真实地分配相应的内存,不使用lazy机制。

内存OOM

当真实去写内存时,应用程序并不能拿到真实的内存时。Linux启动OOM,linux在运行时,会对每一个进程进行out-of-memory打分。大部分主要基于,耗费的内存。耗费的内存越多,打分越高。

cat /proc/<pid>/oom_score
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
int main(int argc, char **argv)
{
    int max = -1;
    int mb = 0;
    char *buffer;
    int i;
#define SIZE 2000
    unsigned int *p = malloc(1024 * 1024 * SIZE);
    printf("malloc buffer: %pn", p);
    for (i = 0; i < 1024 * 1024 * (SIZE/sizeof(int)); i++) {
        p[i] = 123;
        if ((i & 0xFFFFF) == 0) {
            printf("%dMB writtenn", i >> 18);
            usleep(100000);
        }
    }
    pause();
    return 0;
}

定条件:

总内存1G
1、swapoff -a 关掉swap交换
2、echo 1 >
/proc/sys/vm/overcommit_memory
3、内核不去评估系统还有多少空闲内存

Linux进行OOM打分,主要是看耗费内存情况,此外还会参考用户权限,比如root权限,打分会减少30分。

还有OOM打分因子:/proc/pid/oom_score_adj (加减)和 /proc/pid/oom_adj (乘除)。

总结:

1、slab的作用,针对在内核空间小内存分配,和常用数据结构的申请。
2、同样的二次分配器,在用户空间是C库。malloc和free的时候,内存不一定从buddy分配和还给buddy。
3、kmalloc,vmalloc 和malloc的区别

  • kmalloc:申请内存,一般在低端内存区。申请到时,内存已经映射过了,不需要再去改进程的页表。所以,申请到的物理页是连续的。
  • vmalloc:申请内存,申请到就拿到内存,并且已经修改了进程页表的虚拟地址到物理地址的映射。vmalloc()申请的内存并不保证物理地址的连续。
  • 用户空间的malloc:申请内存,申请到并没有拿到,写的时候才去拿到。拿到之后,才去改页表。申请成功,页表只读,只有到写时,发生page fault,才去buddy拿内存。
  • kmalloc和vmalloc针对内核空间,malloc针对用户空间。这些内存,可以来自任何一个Zone。
  • 无论是kmalloc,vmalloc还是用户空间的malloc,都可以使用内存条的不同Zone,无论是highmem zone、lowmem zone 和 DMA zone。

4、如果在从buddy拿不到内存时,会触发Linux对所有进程进行OOM打分。当Linux出现内存耗尽,就kill一个oom score 最高的是那个进程。oom_score,可以根据 oom_adj (-17~25)。

Android/ target=_blank class=infotextkey>安卓的程序,不停地调整前台和后台进程oom_score,当被切换到后台时,oom_score会被调整得比较大。以保证前台的进程不容易因为oom而kill掉。



Tags:映射   点击:()  评论:()
声明:本站部分内容及图片来自互联网,转载是出于传递更多信息之目的,内容观点仅代表作者本人,如有任何标注错误或版权侵犯请与我们联系(Email:2595517585@qq.com),我们将及时更正、删除,谢谢。
▌相关推荐
内核空间 和用户空间申请的内存最终和buddy怎么交互?以及在页表映射上的区别?虚拟地址到物理地址,什么时候开始映射?Buddy的问题分配的力度太大 buddy算法把空闲页面分成1,2,4页,bu...【详细内容】
2021-12-07  Tags: 映射  点击:(25)  评论:(0)  加入收藏
通常服务器会有许多块网卡,因此也可能会连接到不同的网络,在隔离的网络中,某些服务可能会需要进行通信,此时服务器经过配置就可以承担起了转发数据包的功能。一、Windows下实现...【详细内容】
2021-08-17  Tags: 映射  点击:(68)  评论:(0)  加入收藏
一、拓扑 二、IP规划PC1:192.168.1.100/24Gw:192.168.1.1 Client1:192.168.1.200Gw:192.168.1.1 R1:Ge0/0/0:192.168.1.1Ge0/0/1:192.168.1.2 R2:Ge0/0/1:200.1.1.1/29Ge0/...【详细内容】
2021-01-07  Tags: 映射  点击:(1129)  评论:(0)  加入收藏
MyBatis 提供了XML配置和注解配置两种方式。今天就来搞搞这两种方式是如何实现的。MyBatis 的真正强大在于它的语句映射,这是它的魔力所在。由于它的异常强大,映射器的 XML 文...【详细内容】
2020-12-11  Tags: 映射  点击:(185)  评论:(0)  加入收藏
前面讲到过写时复制缺页异常(COW),一般用于父子进程之间共享页,而我们会常见一种缺页异常是匿名映射缺页异常,今天我们就来讨论下这种缺页异常,让大家彻底理解它。注:本文使用linux-5.0内核源代码。文章分为以下几节内容:...【详细内容】
2020-09-10  Tags: 映射  点击:(90)  评论:(0)  加入收藏
作者:前端先锋转发链接:https://mp.weixin.qq.com/s/1sl21P0AHPlbFEq4_Q7hVQ前言Vuex 是一把双刃剑。如果使用得当,Vue 可以使你的工作更加轻松。如果不小心,也会使让的代码混...【详细内容】
2020-09-10  Tags: 映射  点击:(110)  评论:(0)  加入收藏
我用的机器是Redmibook16,计划将左侧的win键与control键盘对调,下面是这款笔记本的键盘布局:我的键盘搜索结果中可以看到很多按部就班修改注册表的方法。建议不要轻易manually...【详细内容】
2020-08-25  Tags: 映射  点击:(60)  评论:(0)  加入收藏
mmap/munmap接口是用户空间的最常用的一个系统调用接口,无论是在用户程序中分配内存、读写大文件,链接动态库文件,还是多进程间共享内存,都可以看到mmap/munmap的身影。mmap/mun...【详细内容】
2020-08-10  Tags: 映射  点击:(271)  评论:(0)  加入收藏
在分段系统中,用户可用二维地址表示程序中的对象,但实际的物理内存仍是一维的字节序列。为此,必须借助段表把用户定义的二维地址映射成一维物理地址。段地址转换与分页地址转换...【详细内容】
2020-08-06  Tags: 映射  点击:(167)  评论:(0)  加入收藏
在IP地址和子网掩码中说了IP地址,在网卡的真正硬件地址MAC 中说了MAC地址,在端口是个什么鬼? 中说了端口。但实际上我们大部分时候更关心的是IP地址和端口。至少在今天我要说的...【详细内容】
2020-06-27  Tags: 映射  点击:(41)  评论:(0)  加入收藏
▌简易百科推荐
作用显示文件或目录所占用的磁盘空间使用命令格式du [option] 文件/目录命令功能显示文件或目录所占用的磁盘空间一些写法的区别du -sh xxx 显示总目录的大小,但是不会列出...【详细内容】
2021-12-23  mitsuhide1992    Tags:du命令   点击:(12)  评论:(0)  加入收藏
什么是linux内核linux就像是一个哲学的最佳实践。如果非要对它评价,我真的不知道该怎么赞叹,我只能自豪地说着:“linux的美丽简直让人沉醉。”我只能说是我处在linux学习的修炼...【详细内容】
2021-12-23  linux上的码农    Tags:linux内核   点击:(15)  评论:(0)  加入收藏
本文将比较 Linux 中 service 和 systemctl 命令,先分别简单介绍这两个命令的基础用法,然后进行比较。从 CentOS 7.x 开始,CentOS 开始使用 systemd 服务来代替 service服务(dae...【详细内容】
2021-12-23  软件架构    Tags:systemctl   点击:(13)  评论:(0)  加入收藏
mv是move的缩写,可以用来移动文件或者重命名文件名,经常用来备份文件或者目录。命令格式mv [选项] 源文件或者目录 目标文件或者目录命令功能mv命令中第二个参数类型的不同(...【详细内容】
2021-12-17  入门小站    Tags:mv命令   点击:(23)  评论:(0)  加入收藏
大数据技术AI Flink/Spark/Hadoop/数仓,数据分析、面试,源码解读等干货学习资料 98篇原创内容 -->公众号 Linux sed 命令是利用脚本来处理文本文件。sed 可依照脚本的指令来处...【详细内容】
2021-12-17  仙风道骨的宝石骑士    Tags:sed命令   点击:(21)  评论:(0)  加入收藏
Node是个啥?  写个东西还是尽量面面俱到吧,所以有关基本概念的东西我也从网上选择性地拿了下来,有些地方针对自己的理解有所改动,对这些概念性的东西有过了解的可选择跳过这段...【详细内容】
2021-12-15  linux上的码农    Tags:node   点击:(21)  评论:(0)  加入收藏
难道只有我一个人觉得Ubuntu的unity桌面非常好用吗?最近把台式机上面的Ubuntu 16.04格式化了,装了黑苹果用了一周,不得不说,MacOS确实很精美,软件生态比Linux丰富很多,比Windows简...【详细内容】
2021-12-14  地球末日村    Tags:ubuntu   点击:(34)  评论:(0)  加入收藏
简介Netstat 命令用于显示各种网络相关信息,如网络连接,路由表,接口状态 (Interface Statistics),masquerade 连接,多播成员 (Multicast Memberships) 等等。输出信息含义执行net...【详细内容】
2021-12-13  窥镜天    Tags:Linux netstat   点击:(26)  评论:(0)  加入收藏
对于较多数量的文件描述符的监听无论是select还是poll系统调用都显得捉襟见肘,poll每次都需要将所有的文件描述符复制到内核,内核本身不会对这些文件描述符加以保存,这样的设计...【详细内容】
2021-12-13  深度Linux    Tags:Linux   点击:(16)  评论:(0)  加入收藏
今天,我们来了解下 Linux 系统的革命性通用执行引擎-eBPF,之所以聊着玩意,因为它确实牛逼,作为一项底层技术,在现在的云原生生态领域中起着举足轻重的作用。截至目前,业界使用范...【详细内容】
2021-12-10  架构驿站    Tags:eBPF   点击:(24)  评论:(0)  加入收藏
最新更新
栏目热门
栏目头条