linux申请大块内存,linux 内存看一篇就够了(多图)
image
正文
0 内存模块
image
1 linux内存总体布局:内存分成用户态和内核态
4G进程地址空间解析
image
image
内核地址空间
image
image
进程地址空间
image
2 地址转换和页表
2.1 地址转换
虚拟内存是指程序使用的逻辑地址。每个进程4G。所有进程共享物理内存4G,所以逻辑地址和物理地址不是一一对应,需要地址转换.
image
image.png
页表由3部分组成:页目录,页面,页内偏移
32bit只有3级 0 -11位:页内偏移OFFSET 12-21位:页面表偏移PT(PTE 页表项.指向一张具体的物理内存页) 22-31位:页面目录偏移PGD
寻址过程如下:
1)操作系统从寄存器CR3获得当前页面目录指针(基地址);
2)基地址+页面目录偏移->页面表指针(基地址);
3)页面表指针+页面表偏移->内存页基址;
4)内存页基址+页内偏移->具体物理内存单元。
页号=逻辑地址/页面大小;页面偏移量=逻辑地址%页面大小 。
页目录保存页表项的地址,页表项保存物理地址,最后1项保存4k页内偏移。
进程页表长这样子:
image
举例说明地址映射:比如要访问线性地址0xBFC0 4FFE(1byte),2进制形式
image
1).mmu先取线性地址高10位(31-22)=767,x4=3068=0xBFC,+cr3=0x3800 0bfc,即页目录项在内存的地址,此地址的内容0x392f f000即页表首地址(页对齐最后12位清0)
2).mmu取线性地址下面10位数(21-12)=4,x4=16=0x10,+0x392f f000=0x392f f010,即页表项在内存的地址,此地址的内容0x3080 4000即物理页面的首地址(页对齐最后12位清0)
3).mmu取线性地址最后12位数(11-0)=4094=0xffe作为低12位,0x3080 4000的前20位作为高20位,组成一个新的32位数0x3080 4ffe即线性地址0xBFC0 4FFE对应的物理地址
2.2 内核页表和进程页表的区别和联系?
进程页表访问:虚拟内存与物理内存的对应。 内核页表:建立物理内存和disk的对应.address_space。
mmap的时候,vmalloc分配内核内存,更改内核页表,然后拷贝内核页表到进程页表.
无论进程页表还是内核页表都在内核中运行,都由内核修改.
经典问题:两个进程虚拟地址相同,物理地址不同。本质就是进程页表的内容不同。
3 内存的分配
3.1 伙伴系统 and slab
伙伴系统分配的最小单位是页(4k). 伙伴系统是一个内存池.
它把所有的空闲页框分组为11个块链表,每个块链表分别包含大小为1,2,4,8,16,32,64,128,256,512和1024个连续的页框.
把空闲的页以2的n次方为单位进行拆分or合并.分配从链表上获取和归还.
比如:k 链表(32)没有空闲块,需要在k+1链表(64)查找,如果仍然没有。在k+2链表(128)查找,找到以后分成1个64,2个32发给k和k+1链表.
链表回收过程相反,临近的空闲块组合,连接到空闲链表上.
image
例如:假设ZONE_NORMAL 有16页内存,此时有人申请一页内存,剩下15页.Buddy算法会把剩下的15页拆分成8+4+2+1,放到不同的链表中去。
slab:内核分配内存通常很小,所以引入了slab的方法. Buddy解决外部内存碎片,slab 解决内部内存碎片.
伙伴系统(buddy system)是以页为单位管理和分配内存.slab是以byte为单位分配内存.
slab分配器是基于对象类型进行内存管理的,每一种对象被划分为一类,例如索引节点对象是一类,进程描述符又是一类,等等 slab分成2种cache,普通cache和专用cache. 每种cache分成3种链表full,paritition,empty.
slab 使用kmalloc分配.
image
3.2 内存分配
内存分配就是向伙伴系统申请内存,然后更改页表形成地址转换.
缺页中断:malloc分配内存即产生缺页中断,缺页中断有两个情况,一种有足够内存,直接分配。另一种情况没有内存,需要先置换后分配.
(1) 进程分配malloc
malloc 分配的最小单位是页.小于128k用brk.malloc 大于128k用mmap.
1): brk原理:brk是堆顶指针,会产生内存空洞.比如:先分配256k,再分配128k,释放前面的256k,因为brk指向的栈顶128k没有回收,所以释放的256k页不会归还os.
brk释放:当brk释放空间少于128k则不会归还os,而是malloc采用链表管理这些空闲内存.
比如:malloc(1) 分配1个字节,os也会分配4k。剩下的4k-1字节全由malloc的空闲内存管理链表管理.
2): mmap
堆和栈之间,独立分配,直接释放. 采用匿名映射分配内存. 缺点在堆栈之间造成内存空洞。
写拷贝:malloc分配内存仅仅分配虚拟内存并没有分配物理内存,根据内存的写拷贝原则,只有访问内存的时候才正式分配物理内存。即malloc分配虚拟内存,memset的时候才真正分配物理内存.
(2) 内核分配内存
1 ) vmalloc
适用场景:在内核中不需要连续的物理地址,而仅仅需要内核空间里连续的虚拟地址的内存块. 比如:将文件读入内核内存.
适用区域: vmalloc 机制则在高端内存映射区分配物理内存.
通过更改内核页表实现内核内存和物理地址的地址转换. vmalloc是从伙伴系统分配内存.
2 ) kmalloc
kmalloc是实地址映射,不需要地址转换.
kmalloc基于slab分配器,slab缓冲区建立在一个连续的物理地址的大块内存之上,所以缓冲对象也是物理地址连续的。
3 ) malloc,vmalloc,kmallc 分配流程
image
3.3 置换和回收
(1)两种情况,一种释放,一种PFRA(类似jvm 垃圾回收内存机制)
(2)页分类(按有无文件背景页面主要分两种):
文件页(file-backed page):有文件背景页面。可以直接和硬盘对应的文件进行交换。
匿名页(anonymous page):无文件背景页面.如进程堆,栈,数据段使用的页等,无法直接跟磁盘交换,但是可以跟swap区进行交换。
(3)哪些内存可以回收
a ) 属于内核的大部分页框是不能够进行回收的,比如内核栈、内核代码段、内核数据段以及大部分内核使用的页框。
b ) 进程使用的页框可以进行回收的,比如进程代码段,进程数据段,进程堆栈,进程访问文件时映射的文件页,进程间共享内存使用的页.
c ) 伙伴系统分配的页面使用者使用free_pages之类的函数主动释放的,页面释放后被直接放归伙伴系统 slab中分配的对象(使用kmem_cache_alloc函数),也是由使用者主动释放的(使用kmem_cache_free函数).
3 页回收方式
a ) 页回写:如果一个很少使用的页的后备存储器是一个块设备(例如文件映射),则可以将内存直接同步到块设备,腾出的页面可以被重用 页交换:如果页面没有后备存储器,则可以交换到特定swap分区,再次被访问时再交换回内存。
b ) 页丢弃:如果页面的后备存储器是一个文件,但文件内容在内存不能被修改(例如可执行文件),那么在当前不需要的情况下可直接丢弃。
页面该回收: 磁盘高速缓存的页面,但是如果页面是脏页面,则丢弃之前必须将其写回磁盘 回收匿名映射的页面,只好先把页面上的数据转储到磁盘,这就是页面交换(swap)。 所有的磁盘高速缓存页面都可回收,所有的匿名映射页面都可交换。
4 页回收算法-LRU
磁盘高速缓存页面(包括文件映射页面)的链表、匿名映射页面的链表 当Linux系统内存有盈余时,内核会尽量多地使用内存作为page cache,提高系统性能,page cache会被加入到文件类型的LRU链表中,当系统内存紧张时,会按一定的算法来回收内存.
下面简单了解下: LRU链表按zone来配置,每个zone中都有一整套LRU链表.page交换调度策略使用.page可能被调度到active_list或者inactive_list队列里.就是使用lru这个list_head. LRU每个zone有两个链表,一个active,一个non-active.
进行页面回收的时候,一是将active链表中最近最少使用的页面移动到inactive链表、二是尝试将inactive链表中最近最少使用的页面回收.
5 页回收时机
直接页面回收(主动触发):“内存严重不足”事件的触发。 周期性回收(被动触发):kswapd进程以水线为触发点,按LRU链表来进行回收。系统会调用函数balance_pgdat(),它主要调用的函数是 shrink_zone() 和 shrink_slab()。
6 反向映射(比如共享文件或者内存)
本质是逆向映射。
正向映射是建立进程页表和物理内存关系用于访问。
逆向映射是回收的时候,查看反向指针rmap,没有页表引用就回收.
多个引用的回收 PFRA处理页面回收的过程中,LRU的inactive链表中的某些页面可能就要被回收了。 如果页面没有被映射,直接回收到伙伴系统即可(对于脏页,先写回、再回收)。否则,还有一件麻烦的事情要处理。因为用户进程的某个页表项正引用着这个页面呢,在回收页面之前,还必须给引用它的页表项一个交待 内核建立了从页面到页表项的反向映射。通过反向映射可以找到一个被映射的页面对应的vma,通过vma->vm_mm->pgd就能找到对应的页表。然后通过page->index得到页面的虚拟地址。再通过虚拟地址从页表中找到对应的页表项。
7 OOM( out of memory )killer
如果操作系统在进行了内存回收操作之后仍然无法回收到足够多的页面以满足上述内存要求,那么操作系统只有最后一个选择,那就是使用 OOM( out of memory )killer,它从系统中挑选一个最合适的进程杀死它,并释放该进程所占用的所有页面
image
4 内存实现
1.jpg
image
5 内存与文件系统
struct
作用
struct file* fd_array[]
用于每个进程打开的文件的指针
struct file* vm _file
用于一个vm_area_struct中all打开文件的指针.vm_file通过struct file中的struct path与struct dentry相关联.
address_space
一个文件对应一个address_space,address_space管理这个文件的所有页缓存。通过radix树管理.
innode
一个文件对应唯一inode struct
struct dentry
通过它的inode指针指向inode,inode与address_space一一对应,至此形成了页缓存与文件系统之间的关联;
vm_ops
文件操作 open,close,nopage
页缓存和address_space
image.png
比如:进程A将文件A读入内核页缓存,然后address_space管理这些页缓存。进程B也要读文件A,它会现在address_space中查找如果存在则直接返回,如果不存在则从文件系统读入. 有了address_space可以多个进程共享读取文件.
image.png
如果两个进程访问一个文件,其中一个进程写文件,那么采用匿名文件方式.
image.png
6 共享内存
1 mmap 有2个功能:
(1) malloc 底层实现. 参见上文
(2) 映射文件读写. 本质是进程可以访问内核内存,减少了read,write函数所需要的内核拷贝到用户态.请看https://blog.csdn.net/fdsafwagdagadg6576/article/details/107584821
2 shm*() 函数。就是匿名文件
image.png
7 malloc的实现
8 内存零拷贝技术
9 valgraind
阿佳妮1.jpg
linux申请大块内存,linux 内存看一篇就够了(多图)相关推荐
- 学习linux内核-- 内存,看一篇就够了(多图)
内存模块 1 linux内存总体布局:内存分成用户态和内核态 4G进程地址空间解析 内核地址空间 进程地址空间 2 地址转换和页表 2.1 地址转换 虚拟内存是指程序使用的逻辑地址.每个进程4G.所有 ...
- centos 上传jar 命令_想在Linux上上传下载文件?看这篇就够了
自从上次给我可爱的同事们普及了SecureCRT+FX以后,他们都开始喜欢上用SecureFX上传下载文件,主要是连JS和CSS这样的小文件他们竟然也用SecureFX,看得我这个捉急,那就再写一篇番 ...
- TF卡里删掉文件后内存没变大_双11,TF卡,SD卡,读卡器如何选,看这篇就够了...
此文章发布已经半年有余,各大厂家推出了很多新的SD卡,且SD卡组织也推出了新的标准,所以这篇文章的内容已经有些过时,还得烦请各位移步到新的文章: 黄昏百分百:TF卡,SD卡,读卡器,USB拓展坞如何选 ...
- Docker入门实战看这篇就够了(最新详细以及踩过的坑)
Docker入门实战看这篇就够了 前言 初识 是什么 容器与虚拟机 能干什么 去哪玩 安装 先决条件 查看自己的内核 安装所需的软件包(支持devicemapper存储类型) 设置镜像的仓库 设置yu ...
- NDK撩妹三部曲(四)—NDK 开发如何优雅的定位 Native 异常,看这篇就够了
NDK 开发如何优雅的定位 Native 异常,看这篇就够了 从何说起? 摘要 案例实操 aaddr2line objdump ndk-stack 1.假设我们已经通过 adb logcat 拿到了程 ...
- 【超全汇总】学习数据结构与算法,计算机基础知识,看这篇就够了【ZT帅地】2020-3-7
https://blog.csdn.net/m0_37907797/article/details/104029002 由于文章有点多,并且发的文章也不是一个系列一个系列发的,不过我的文章大部分都是围 ...
- Cookie、Session、Token、JWT 看一篇就够了
目录 Cookie.Session.Token.JWT 看一篇就够了 什么是认证(Authentication) 什么是授权(Authorization) 什么是凭证(Credentials) 怎么让 ...
- Android画中画模式-看这篇就够啦
最近做做播放器,有个浮窗播放的需求,两种实现方式,一种是申请浮窗权限,创建浮窗参考 flowWindow,一种是采用画中画模式(8.0以上) 关于画中画 Android 8.0 Oreo(API Le ...
- .NET Core实战项目之CMS 第二章 入门篇-快速入门ASP.NET Core看这篇就够了
本来这篇只是想简单介绍下ASP.NET Core MVC项目的(毕竟要照顾到很多新手朋友),但是转念一想不如来点猛的(考虑到急性子的朋友),让你通过本文的学习就能快速的入门ASP.NET Core.既 ...
最新文章
- android graphic:canvas
- Linux下定时切割Mongodb数据库日志并删除指定天数前的日志记录(转)
- oracle 绑定变量模糊查询,求助-ACTIVE DG 异常shutdown
- Postman Forbidden (CSRF token missing or incorrect.)
- 双系统环境下 CentOS 挂载 Windows NTFS 磁盘分区
- JDK6升级JDK8踩雷
- 萤火虫小程序_成都以北2h的森林小镇!养在深闺的萤火虫、穿行山间的火车,在这露营解锁夏天的小秘密...
- 颜色对照表(二)(16进制、RGB、CMYK、HSV、中英文名)
- QGis二次开发:预览几何图形,QgsRubberBand的应用
- 《Java并发编程的艺术》——线程(笔记)
- 定时器实验循环彩灯C语言,单片机实验三-定时器实验
- npm、yarn、pnpm、cnpm对比其优劣势
- feedback算法C语言,Learner Reviews Feedback for 计算导论与C语言基础 Course | Coursera
- 自我鉴定200字大专生计算机专业,大专毕业自我鉴定200字
- 微信小程序如何添加新的icon图标
- 拼多多+阿里+今日头条+京东众多大厂Java面经合集(2020面试总结)
- JUC-15. 原子类(Atomic)
- 如何带领团队?各位指点江山吧!
- [原创]Linux下undefinednbsp;refe…
- 卷积神经网络学习路线(十七) | Google CVPR 2017 MobileNet V1
热门文章
- Webdw1.0版本已经整合完毕发布到github上了
- 哔哩哔哩视频合并 B站缓存视频合并 安卓版 音视频合并 基于ffmpeg
- R语言-机器学习概述
- 计算机博士要学数学吗,科学网—计算机博士与数学 - 马飞的博文
- 重新系统(win11)以后,西部硬盘(机械硬盘)识别不了
- 蓝桥杯题目:九宫幻方(C++实现)(DFC)(打卡1)
- docker部署smokeping监控网络掉包
- node : 无法将“node”项识别为 cmdlet、函数、脚本文件或可运行程序的名称。请检查名称的拼写,如果包括路径,请确保路径正 确,然后再试一次 的解决方案
- SSM+传统民间工艺线上商城 毕业设计-附源码181701
- 使用阿里云来搭建视频直播服务