首先我先说明最近才真的用心整理和查看linux内存管理方面知识,之所以写这篇博客只是为了整理。

fightting

参考书籍 Linux 内核源代码情景分析
深入理解Linux虚拟内存管理

首先还是上一些关于虚拟内存要问的一些问题吧。

什么是线性地址,逻辑地址,虚拟地址,物理地址

cpu总线发出的地址是什么地址,需要什么过程才能转换为物理地址

什么是内存的分段技术,什么是分页技术,

实模式和保护模式

多级页映射的问题,页目录和页表

虚拟地址空间和虚拟内存的概念

如何获取一个虚拟地址对应的物理地址

32为下的LINUX操作系统虚拟地址映射问题

缺页异常处理do_page_fault

slab机制和伙伴系统

虚拟内存管理和物理内存管理

总共就这莫多问题把


地址概念问题

逻辑地址,逻辑地址就是我们调试和打印的地址,它只是一种偏移地址

线性地址 线性地址就是逻辑地址加上段地址(具体自己查原因(这也是x86体系下的问题(linux下段的地址都是0)))

虚拟地址 保护模式下的段地址+offset

真实内存的地址地址总线上的地址

分段机制

想死啊这是第四次写这个东西了前三次都没有保存。算了继续来吧就当在记一下

  • 分段机制的寻址物理地址=段地址+offset
  • 保护模式下的寻址 物理地址=段描述表的地址+offset 这个也叫线性地址。
    防止越权访问以及越届访问的情况的发生。


先给个大的概念,物理内存是供的关系而虚拟内存是需的关系。举个类似malloc
如果一个进程对虚拟空间的使用都是有限制的,通常都是使用的非连续的部分,比如代码段和数据段 堆栈这些离散的空间,对应的虚拟存储的管理。
首先cpu得到是线性地址,如果要找到实际的物理地址,就要通过多级页映射。具体而言分为4步
虚拟地址最高的那1个字段是在PGD查找当前的表项得到的是中间目录,通过第二个所对应的下标找到对应的页面表,在页面表中找到存放物理页的指针,最后的段是表示offset所以物理页的地址加上对应的偏移就是最终的物理得知。

物理内存页的周转(物理内存管理)

内存页的申请和释放具体这个过程如下
总体流程
1、空闲。
页面page数据结构通过其队列头链入对应管理区空闲队列free_area。页面计数count=0
2、分配
通过函数_alloc_pages()或_get_free_page()从空闲队列分配内存页面,并将所分配页面计数为1,其从free_area队列移除
如果无进行内存交换操作
3、上个页面链入活跃队列active_list,并且至少有一个进程的用户空间指向该页面。每当为其页面再建立或恢复映射时,页面计数count+1;
4、每当断开页面映射,页面计数-1。如果修改了页面内容且页面不再用即count=0,则链入inactive_dirty_list队列。
5、将不活跃脏页面写入交换设备,从inactive_dirty_list移到inactive_clean_list队列。
6、如果之后又收到访问,则又到活跃页面并恢复映射。
7、需要时则从“干净队列”中回收页面。

伙伴算法

参考https://www.cnblogs.com/cherishui/p/4246133.html
伙伴算法的实现原理
为了便于页面的维护,将多个页面组成内存块,每个内存块都有 2 的方幂个页,方幂的指数被称为阶 order。order相同的内存块被组织到一个空闲链表中。伙伴系统基于2的方幂来申请释放内存页。
当申请内存页时,伙伴系统首先检查与申请大小相同的内存块链表中,检看是否有空闲页,如果有就将其分配出去,并将其从链表中删除,否则就检查上一级,即大小为申请大小的2倍的内存块空闲链表,如果该链表有空闲内存,就将其分配出去,同时将剩余的一部分(即未分配出去的一半)加入到下一级空闲链表中;如果这一级仍没有空闲内存;就检查它的上一级,依次类推,直到分配成功或者彻底失败,在成功时还要按照伙伴系统的要求,将未分配的内存块进行划分并加入到相应的空闲内存块链表
在释放内存页时,会检查其伙伴是否也是空闲的,如果是就将它和它的伙伴合并为更大的空闲内存块,该检查会递归进行,直到发现伙伴正在被使用或者已经合并成了最大的内存块。

缺点只有对页外的内存碎片就进行解决,并没有对页内的内存碎片进行解决,合并必须在同一个内存块上。

slab算法:

一般来说,伙伴算法的改进算法用于操作系统分配和回收内存,而且内存块的单位较大,利于Linux使用的伙伴算法以页为单位.对于小块内存的分配和回收,伙伴算法就显得有些得不偿失了.
对于小块内存,一般采用slab算法,或者叫做slab机制.
Linux 所使用的 slab 分配器的基础是 Jeff Bonwick 为SunOS 操作系统首次引入的一种算法。Jeff的分配器是围绕对象缓存进行的。在内核中,会为有限的对象集(例如文件描述符和其他常见结构)分配大量内存。Jeff发现对内核中普通对象进行初始化所需的时间超过了对其进行分配和释放所需的时间。因此他的结论是不应该将内存释放回一个全局的内存池,而是将内存保持为针对特定目而初始化的状态。例如,如果内存被分配给了一个互斥锁,那么只需在为互斥锁首次分配内存时执行一次互斥锁初始化函数(mutex_init)即可。后续的内存分配不需要执行这个初始化函数,因为从上次释放和调用析构之后,它已经处于所需的状态中了。
Linux slab分配器使用了这种思想和其他一些思想来构建一个在空间和时间上都具有高效性的内存分配器。
图中给出了 slab结构的高层组织结构。在最高层是 cache_chain,这是一个 slab 缓存的链接列表。这对于 best-fit算法非常有用,可以用来查找最适合所需要的分配大小的缓存(遍历列表)。cache_chain 的每个元素都是一个 kmem_cache 结构的引用(称为一个 cache)。它定义了一个要管理的给定大小的对象池。
每个缓存都包含了一个 slabs 列表,这是一段连续的内存块(通常都是页面)。存在3 种 slab:
slabs_full:完全分配的slab
slabs_partial:部分分配的slab
slabs_empty:空slab,或者没有对象被分配
slab 列表中的每个 slab都是一个连续的内存块(一个或多个连续页),它们被划分成一个个对象。这些对象是从特定缓存中进行分配和释放的基本元素。注意 slab 是 slab分配器进行操作的最小分配单位,因此如果需要对 slab 进行扩展,这也就是所扩展的最小值。通常来说,每个 slab 被分配为多个对象。
由于对象是从 slab 中进行分配和释放的,因此单个 slab 可以在 slab列表之间进行移动。例如,当一个 slab中的所有对象都被使用完时,就从slabs_partial 列表中移动到 slabs_full 列表中。当一个 slab完全被分配并且有对象被释放后,就从 slabs_full 列表中移动到slabs_partial 列表中。当所有对象都被释放之后,就从 slabs_partial 列表移动到 slabs_empty 列表中。
slab背后的动机
传统的内存管理模式相比, slab缓存分配器提供了很多优点。首先,内核通常依赖于对小对象的分配,它们会在系统生命周期内进行无数次分配。slab缓存分配器通过对类似大小的对象进行缓存而提供这种功能,从而避免了常见的碎片问题。slab分配器还支持通用对象的初始化,从而避免了为同一目而对一个对象重复进行初始化。最后,slab分配器还可以支持硬件缓存对齐和着色,这允许不同缓存中的对象占用相同的缓存行,从而提高缓存的利用率并获得更好的性能。

虚拟内存管理

如果说物理内存管理是对供的管理,那么虚拟内存是对需的管理。
Linux 的虚拟内存管理有几个关键概念:
每个进程有独立的虚拟地址空间,进程访问的虚拟地址并不是真正的物理地址
虚拟地址可通过每个进程上页表与物理地址进行映射,获得真正物理地址
如果虚拟地址对应物理地址不在物理内存中,则产生缺页中断,真正分配物理地址,同时更新进程的页表;如果此时物理内存已耗尽,则根据内存替换算法淘汰部分页面至物理磁盘中。

定期的页面交换策略

最简单的一种情况时,如果访问虚拟页时发现该页不在实际的内存上,或者没有分配到实际物理页。那么就会发生缺页中断。缺页中断做的事就是将磁盘的页放入内存,并产生映射关系。或者分配页。
但是这块却又一个问题,对于物理内存而言不可能随时都有足够的内存页,所以它回选择置换一个长时间没有使用的页换到swap分区,但是如果 每当缺页的时候在去换,使得cpu此刻过于繁忙,所以操作系统会在一隔段时间内选择一些页置换的swap分区上,保证内存中有合适的空闲页。具体算法位LRU 算法但是这却造成了一个很严重的问题。如果当前页刚被置换出去后如果访问要重新从磁盘上想内存中调。这是一个很难受的问题。这个问题也叫做也页面的抖动。

页面抖动的解决,可以将换出和和页面释放分开。

具体而言加入一个缓冲队列(也叫不活跃的队列)。
首先如果该页因为很久没被访问,那么首先他会被放到缓冲队列上,然后将其写入到磁盘,但是并不释放的当前的物理页,只是解除当前的物理页和虚拟页之间的映射。然后等待该页的老化,如果该页被访问,直接从缓冲队列上取走并且放入到活跃的队列上,重新建立起映射关系。如果没被访问等待页的老化和回收。但是这块也有一个很重要的问题,如果当前的物理页在磁盘,如果在物理页中被修改,重新老化释放的话就要写会磁盘,(脏页),如果没有被修改,在缓冲队列放入时候就不会写回磁盘。
(剩下的问题就在这个知乎中)
https://zhuanlan.zhihu.com/p/26137521?utm_source=qq&utm_medium=social

Linux 内存管理。相关推荐

  1. Windows内存管理和linux内存管理

    windows内存管理 windows 内存管理方式主要分为:页式管理,段式管理,段页式管理. 页式管理的基本原理是将各进程的虚拟空间划分为若干个长度相等的页:页式管理把内存空间按照页的大小划分成片或 ...

  2. 万字长文,别再说你不懂Linux内存管理了(合辑),30 张图给你安排的明明白白...

    之前写了两篇详细分析 Linux 内存管理的文章,读者好评如潮.但由于是分开两篇来写,而这两篇内容其实是有很强关联的,有读者反馈没有看到另一篇读起来不够不连贯,为方便阅读这次特意把两篇整合在一起,看这 ...

  3. 别再说你不懂Linux内存管理了,10张图给你安排的明明白白!

    来自:后端技术学堂 过去的一周有点魔幻,有印象的有三个新闻:天猫总裁绯闻事件,蘑菇街裁员,不可能打工的周某也放出来了.三件事,两件和互联网行业相关,好像外面的世界很是精彩啊!吃瓜归吃瓜,学习还是不能落 ...

  4. Linux内存管理原理【转】

    转自:http://www.cnblogs.com/zhaoyl/p/3695517.html 本文以32位机器为准,串讲一些内存管理的知识点. 1. 虚拟地址.物理地址.逻辑地址.线性地址 虚拟地址 ...

  5. Linux内存管理【转】

    转自:http://www.cnblogs.com/wuchanming/p/4360264.html 转载:http://www.kerneltravel.net/journal/v/mem.htm ...

  6. Linux内存管理之高端内存映射

    一:引子 我们在前面分析过,在linux内存管理中,内核使用3G->4G的地址空间,总共1G的大小.而且有一部份用来做非连续空间的物理映射(vmalloc).除掉这部份空间之外,只留下896M大 ...

  7. Linux内存管理原理

    本文以32位机器为准,串讲一些内存管理的知识点. 1. 虚拟地址.物理地址.逻辑地址.线性地址 虚拟地址又叫线性地址.linux没有采用分段机制,所以逻辑地址和虚拟地址(线性地址)(在用户态,内核态逻 ...

  8. Linux内存管理 (2)页表的映射过程

    专题:Linux内存管理专题 关键词:swapper_pd_dir.ARM PGD/PTE.Linux PGD/PTE.pgd_offset_k. Linux下的页表映射分为两种,一是Linux自身的 ...

  9. Linux内存管理 (4)分配物理页面

    专题:Linux内存管理专题 关键词:分配掩码.伙伴系统.水位(watermark).空闲伙伴块合并. 我们知道Linux内存管理是以页为单位进行的,对内存的管理是通过伙伴系统进行. 从Linux内存 ...

  10. Linux 交换内存空间原理(swap)(Linux内存管理)(cgroups)

    文章目录 什么是swap? 为什么需要swap? swap的缺点? 到底要不要swap? 内存不够用 内存勉强够用 内存充裕 桌面环境 服务器环境 swap大小配置多少比较合适? 怎么配置swap? ...

最新文章

  1. sqlserver2008清除日志方法_服务器磁盘使用率100%解决方法
  2. ST公司STM32F4与STM32F1的区别
  3. 什么叫做“假学习”?什么叫做“真学习”?
  4. docker容器的重启策略:通过--restart来指定
  5. 8.初探python之集合
  6. 基本概念学习(8000)---兼容机
  7. Mac 打开jupyter
  8. PX4编译文件 Makefile 剖析
  9. 汽车LED驱动器MPQ3326替代替换
  10. ios订阅其他国家节假日日历
  11. 蓝桥杯比赛时间在什么时候_什么时候立冬2020年农历具体时间
  12. java.lang.Class cannot be cast to java.lang.reflect.ParameterizedType
  13. latex设置页面边距,页面大小,页边距,geometry宏包
  14. AliOS Things入门(1) 基于STM32L4与MDK搭建AliOS Things2.1.0开发环境
  15. 那些年啊,那些事——一个程序员的奋斗史 ——21
  16. Informix 12.10版本新特性-2
  17. 2016年最新版App内购买详细指南
  18. 微信小程序开发自学笔记 —— 九、微信开发者工具
  19. 15 年没写代码,濒临被裁,50 岁开发者如何绝地求生?
  20. Linux中传统的IPC机制

热门文章

  1. part-4 运放噪声快速计算
  2. 基于FPGA的视频图像拼接融合(附源码)。
  3. 电脑连不上网,排查原因
  4. 输入一段英文字符,统计每个小写字母的出现次数
  5. android stuio修改代码参考线和智能换行
  6. 职业生涯步步高(转)
  7. 原始资料的收集方法———定性资料的收集
  8. 5G和MEC在工业互联网中的应用探讨
  9. 云速美建站手机端使用百度app打开手机端网站闪退的问题
  10. 北京化工大学计算机复试面试题,北京化工大学综合素质测试面试题历年总结