zoukankan      html  css  js  c++  java
  • [精华] Linux内存:内存管理的实质

    [精华] Linux内存:内存管理的实质


    http://www.chinaunix.net 作者:frank_seng  发表于:2009-07-27 23:23:52
    发表评论】 【查看原文】 【Linux讨论区】【关闭

    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等方式获取内存时,也不会涉及到该物理页面,原理同前所述。
  • 相关阅读:
    JavaScript
    94.Binary Tree Inorder Traversal
    144.Binary Tree Preorder Traversal
    106.Construct Binary Tree from Inorder and Postorder Traversal
    105.Construct Binary Tree from Preorder and Inorder Traversal
    90.Subsets II
    78.Subsets
    83.Merge Sorted Array
    80.Remove Duplicates from Sorted Array II
    79.Word Search
  • 原文地址:https://www.cnblogs.com/wickedboy237/p/3074893.html
Copyright © 2011-2022 走看看