Linux内存:内存管理的实质

简介: 1. 内核初始化:      * 内核建立好内核页目录页表数据库,假设物理内存大小为len,则建立了[3G--3G+len]::[0--len]这样的虚地址vaddr和物理地址paddr的线性对应关系;      * 内核建立一个page数组,page数组和物理页面系列完全是线性对应...

1. 内核初始化: 
    * 内核建立好内核页目录页表数据库,假设物理内存大小为len,则建立了[3G--3G+len]::[0--len]这样的虚地址vaddr和物理地址paddr的线性对应关系; 
    * 内核建立一个page数组,page数组和物理页面系列完全是线性对应,page用来管理该物理页面状态,每个物理页面的虚地址保存在page->virtual中; 
    * 内核建立好一个free_list,将没有使用的物理页面对应的page放入其中,已经使用的就不用放入了; 
2. 内核模块申请内存vaddr = get_free_pages(mask,order): 
    * 内存管理模块从free_list找到一个page,将page->virtual作为返回值,该返回值就是对应物理页面的虚地址; 
    * 将page从free_list中脱离; 
    * 模块使用该虚拟地址操作对应的物理内存; 
3. 内核模块使用vaddr,例如执行指令mov(eax, vaddr): 
    * CPU获得vaddr这个虚地址,利用建立好的页目录页表数据库,找到其对应的物理内存地址; 
    * 将eax的内容写入vaddr对应的物理内存地址内; 
4. 内核模块释放内存free_pages(vaddr,order): 
    * 依据vaddr找到对应的page; 
    * 将该page加入到free_list中; 
5. 用户进程申请内存vaddr = malloc(size): 
    * 内存管理模块从用户进程内存空间(0--3G)中找到一块还没使用的空间vm_area_struct(start--end); 
    * 随后将其插入到task->mm->mmap链表中; 
6. 用户进程写入vaddr(0-3G),例如执行指令mov(eax, vaddr): 
    * CPU获得vaddr这个虚地址,该虚地址应该已经由glibc库设置好了,一定在3G一下的某个区域,根据CR3寄存器指向的current->pgd查当前进程的页目录页表数据库,发现该vaddr对应的页目录表项为0,故产生异常; 
    * 在异常处理中,发现该vaddr对应的vm_area_struct已经存在,为vaddr对应的页目录表项分配一个页表; 
    * 随后从free_list找到一个page,将该page对应的物理页面物理首地址赋给vaddr对应的页表表项,很明显,此时的vaddr和paddr不是线性对应关系了; 
    * 将page从free_list中脱离; 
    * 异常处理返回; 
    * CPU重新执行刚刚发生异常的指令mov(eax, vaddr); 
    * CPU获得vaddr这个虚地址,根据CR3寄存器指向的current->pgd,利用建立好的页目录页表数据库,找到其对应的物理内存地址; 
    * 将eax的内容写入vaddr对应的物理内存地址内;   
7. 用户进程释放内存vaddr,free(vaddr): 
    * 找到该vaddr所在的vm_area_struct; 
    * 找到vm_area_struct:start--end对应的所有页目录页表项,清空对应的所有页表项; 
    * 释放这些页表项指向物理页面所对应的page,并将这些page加入到free_list队列中; 
    * 有必要还会清空一些页目录表项,并释放这些页目录表项指向的页表; 
    * 从task->mm->mmap链中删除该vm_area_struct并释放掉; 
综合说明: 
    * 可用物理内存就是free_list中各page对应的物理内存; 
    * 页目录页表数据库的主要目的是为CPU访问物理内存时转换vaddr-->paddr使用,分配以及释放内存时不会用到,但是需要内核内存管理系统在合适时机为CPU建立好该库; 
    * 对于用户进程在6中获得的物理页面,有两个页表项对应,一个就是内核页目录页表数据库的某个pte[i ],一个就是当前进程内核页目录页表数据库的某个 pte[j],但是只有一个page和其对应。如果此时调度到其他进程,其他进程申请并访问某个内存,则不会涉及到该物理页面,因为其分配时首先要从 free_list中找一个page,而该物理页面对应的page已经从free_list中脱离出来了,因此不存在该物理页面被其他进程改写操作的情况。内核中通过get_free_pages等方式获取内存时,也不会涉及到该物理页面,原理同前所述。

相关文章
|
2月前
|
缓存 监控 Linux
Linux内存问题排查命令详解
Linux服务器卡顿?可能是内存问题。掌握free、vmstat、sar三大命令,快速排查内存使用情况。free查看实时内存,vmstat诊断系统整体性能瓶颈,sar实现长期监控,三者结合,高效定位并解决内存问题。
261 0
Linux内存问题排查命令详解
|
10月前
|
缓存 Linux
linux 手动释放内存
在 Linux 系统中,内存管理通常自动处理,但业务繁忙时缓存占用过多可能导致内存不足,影响性能。此时可在业务闲时手动释放内存。
510 17
|
6月前
|
缓存 Linux 数据安全/隐私保护
Linux环境下如何通过手动调用drop_caches命令释放内存
总的来说,记录住“drop_caches” 命令并理解其含义,可以让你在日常使用Linux的过程中更加娴熟和自如。
1203 23
|
监控 Linux
如何检查 Linux 内存使用量是否耗尽?这 5 个命令堪称绝了!
本文介绍了在Linux系统中检查内存使用情况的5个常用命令:`free`、`top`、`vmstat`、`pidstat` 和 `/proc/meminfo` 文件,帮助用户准确监控内存状态,确保系统稳定运行。
2232 6
|
8月前
|
监控 Linux Python
Linux系统资源管理:多角度查看内存使用情况。
要知道,透过内存管理的窗口,我们可以洞察到Linux系统运行的真实身姿,如同解剖学家透过微观镜,洞察生命的奥秘。记住,不要惧怕那些高深的命令和参数,他们只是你掌握系统"魔法棒"的钥匙,熟练掌握后,你就可以骄傲地说:Linux,我来了!
294 27
|
9月前
|
消息中间件 Linux
Linux中的System V通信标准--共享内存、消息队列以及信号量
希望本文能帮助您更好地理解和应用System V IPC机制,构建高效的Linux应用程序。
382 48
|
9月前
|
缓存 NoSQL Linux
Linux系统内存使用优化技巧
交换空间(Swap)的优化 禁用 Swap sudo swapoff -a 作用:这个命令会禁用系统中所有的 Swap 空间。swapoff 命令用于关闭 Swap 空间,-a 参数表示关闭 /etc/fstab 文件中配置的所有 Swap 空间。 使用场景:在高性能应用场景下,比如数据库服务器或高性能计算服务器,禁用 Swap 可以减少磁盘 I/O,提高系统性能。
378 3
|
9月前
|
缓存 Linux
Linux查看内存命令
1. free free命令是最常用的查看内存使用情况的命令。它显示系统的总内存、已使用内存、空闲内存和交换内存的总量。 free -h • -h 选项:以易读的格式(如GB、MB)显示内存大小。 输出示例: total used free shared buff/cache available Mem: 15Gi 4.7Gi 4.1Gi 288Mi 6.6Gi 9.9Gi Swap: 2.0Gi 0B 2.0Gi • to
739 2
|
缓存 Java Linux
如何解决 Linux 系统中内存使用量耗尽的问题?
如何解决 Linux 系统中内存使用量耗尽的问题?
1073 59
如何在 Linux 系统中查看进程占用的内存?
如何在 Linux 系统中查看进程占用的内存?
1768 58

热门文章

最新文章