Linux内核 申请和释放内存流程

2023-05-16

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等方式获取内存时,也不会涉及到该物理页面,原理同前所述。
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

Linux内核 申请和释放内存流程 的相关文章

  • NLP中三种特征抽取器的优与劣

    RNN LSTM GRU xff1a 缺点 xff08 1 xff09 xff1a 无法并行 xff0c 因此速度较慢 xff08 2 xff09 xff1a RNN无法很好地学习到全局的结构信息 xff0c 尤其对于序列结构很长的 CNN
  • python List中元素两两组合

    aa span class token operator 61 span span class token punctuation span span class token string 39 a 39 span span class t
  • JRE not compatible with project .class file compatibility: 1.7

    电脑上刚装了jdk1 7 xff0c 运行一般程序的时候没有出现什么问题 xff0c 由于内存不够用 xff0c 在设置虚拟内存时却出现问题 xff0c 如下 xff1a 还好找到了解决办法 xff0c 错误的原因是JRE库配置与Java
  • BufferedWriter 的 flush() 方法

    package com corpus import java io import java util List import edu stanford nlp ling HasWord import edu stanford nlp lin
  • 正则表达式匹配连续多个空格或tab空格

    Pattern p 61 Pattern compile 34 s 2 t 34 Matcher m 61 p matcher str String strNoBlank 61 m replaceAll 34 34 System out p
  • LaTex中插入花体字母

    特别要注意的是 xff1a 在LaTeX中 xff0c 别把希腊字母和英文的花体字母搞混哦 xff0c 哈哈 举个例子 xff1a 后面显示的 X 不是希腊字母 西 即 也就是说不能通过 Chi 的方式插入这个特殊符号 xff0c 正确的花
  • 气哭了的C++调试,cmake 找不到 eigen

    这才刚刚开头 xff0c 可是就是不知道错误在哪里 xff1f 百度了问题后 xff0c 打开了很多很多相关的解答 xff0c 从昨天上午遇到这个问题 xff0c 历经昨天下午和晚上 xff0c 还是错误 xff0c 终于在今天上午圆满解决
  • 对ORACLE SCN的理解

    1 SCN数值实际来源于系统的timestamp xff0c 这个实际可以证明 select current scn from v database select timestamp to scn sysdate from dual 这两个
  • Ubuntu 下 终端界面转图形界面

    在运行程序的时候 xff0c 错误的使用了快捷键 ctrl 43 alt 43 F10 然后 unbuntu就黑屏了 xff0c 整个界面只剩下左上角有一个白色的字符在闪 xff0c 然后 Ctrl 43 alt 43 F2时跳出终端的登录
  • python错误:TypeError: 'module' object is not callable

    TrainCorpusStructure py 文件中的代码如下 xff1a class TrainCorpusStructure inputs 61 Demo py中的代码如下 xff1a from corpusProcess impor
  • python 除法保留两位小数点

    span class hljs operator a span 61 span class hljs number 1 span b 61 span class hljs number 3 span print span class hlj
  • pytorch中contiguous()

    contiguous xff1a view只能用在contiguous的variable上 如果在view之前用了transpose permute等 xff0c 需要用contiguous 来返回一个contiguous copy 一种可
  • tensorflow中control_flow_ops.while_loop

    self h0 61 tf zeros self batch size self hidden dim self h0 61 tf stack self h0 self h0 相当于 h0和C0 generator on initial r
  • k8s基础

    目录 一 基本介绍 二 组件介绍 1 master组件 2 node组件 三 核心概念 1 Pod 2 controller 3 service 四 单master搭建集群 1 系统初始化 2 安装k8s核心组件 3 容器化安装其他插件 4
  • 论文解读:Tips and Tricks for Visual Question Answering: Learnings from the 2017 Challenge

    这是关于VQA问题的第十二篇系列文章 这篇论文具有很强的指导意义 xff0c 本篇文章将介绍论文 xff1a 主要思想 xff1b 模型方法 xff1b 试验细节 有兴趣可以查看原文 xff1a Tips and Tricks for Vi
  • 总结2014——迷茫以及迷茫过后的坚持

    首先 xff0c 借用一句话和大家共勉 xff1a 少一些功利主义的追求 xff0c 多一些不为什么的坚持 xff01 xff01 不知不觉15年也快过了1个月了 xff0c 还是想着要为14年做一下总结 xff1a 记录一下自己的历程 今
  • 在faster rcnn中使用soft nms,faster rcnn的改进(一)

    1 背景介绍 我的项目是利用faster rcnn检测kiiti数据集 xff0c 用原始nms xff0c iters 61 10000的情况下 xff0c 得到的mAP 61 0 586 在改用soft nms后 xff0c 其他参数均
  • 建立DATAGUARD最大保护模式-测试手记

    建立DATAGUARD 最大保护模式 xff08 自写 xff09 xff08 备注 xff1a 本文档符合最大保护模式 xff0c 所有参数均为最大保护模式下适用 xff0c 其他模式不适用 xff09 1 主库 xff0c 启动归档 x
  • docker中安装ping | vim | nginx镜像

    docker安装nginx镜像并常见nginx容器 docker pull nginx latest docker run detach publish 9999 80 name nginxSer restart unless stoppe
  • 从操作系统内核解释电脑死机原理

    关于电脑死机的原因或者说原理 xff0c 即电脑为什么会死机 xff0c 电脑死机时计算机底层都发生了什么 一直不太明白 xff0c 在网上也查过相关的资料 xff0c 但是都没有找到自己想要的 网上谈的都是外部导致电脑死机的原因 xff0

随机推荐

  • 自己动手写操作系统第二章 pmtest1.asm分析

    34 pm inc 34 描述符 Usage Descrptor Base Limit Attr Base dd Limit dd Low 20 bits available Attr dw lower 4 bits of higher b
  • Linux 0.11 内核在内核空间创建进程时不使用写时复制技术

    在Linux0 12内核完全剖析中 xff0c 有这样一段话 34 由于创建新进程的过程是通过完全复制父进程代码段和数据段的方式实现 xff0c 因此在首次使用fork 创建新进程init 时 xff0c 为了确保新进程用户态栈中没有进程0
  • putty 登陆VMware虚拟机下的linux系统

    物理机的操作系统是Windows XP 虚拟机是在VMware上安装的CentOS xff0c 版本是5 6 因为每次登陆虚拟机鼠标会被限定在虚拟机的登陆界面 xff0c 所以想通过远程登陆工具来登陆虚拟机 虚拟机使用的网络是桥接模式 注意
  • Minx内核中scanf函数实现代码

    include lt stdio h gt include lt stdarg h gt include 34 loc incl h 34 int scanf const char format va list ap int retval
  • 双系统Linux下突然挂载Windows分区失败

    问题描述 xff0c 装了双系统之后 xff0c 一开始在Linux下还能访问Windows的分区 xff0c 可是突然之间就不能访问了 xff0c 错误信息如下 xff1a Error mounting dev sda1 at media
  • 对Linux0.11 "内核空间不使用写时复制机制" 本质理解

    一个页面被多个进程共享 xff0c 每当一个进程产生一次写保护 错误 xff0c 内核将给进程分配一个新的物理页面 xff0c 将共享页面的内容复制过来 xff0c 新的页面将设置为可读写 xff0c 而共享页面仍然是只读的 xff0c 只
  • Session && Cookie

  • windowsxp远程桌面端口号改变的位置

    HKEY LOCAL MACHINE SYSTEM CurrentControlSet Control Terminal Server Wds rdpwd Tds tcp 下的PortNamber HKEY LOCAL MACHINE SY
  • linux0.11 进程切换

    move to user mode是在堆栈中创建一个任务切换的假象 xff0c 用iret跳转到外层3 xff0c 这样cpu就会自动根据tr加载tss xff0c 并初始化各个寄存器运行任务0 所以 xff0c 任务0其实就是内核空间中的
  • Linux0.11 进程0

    Linux中1号进程是由0号进程来创建的 xff0c 因此必须要知道的是如何创建0号进程 xff0c 由于在创建进程时 xff0c 程序一直运行在内核态 xff0c 而进程运行在用户态 xff0c 因此创建0号进程涉及到特权级的变化 xff
  • Linux0.11 由进程睡眠函数sleep_on()中的堆栈变量tmp引发的思考 关于进程内核堆栈

    sleep on cpp view plaincopy 功能 xff1a 当前进程进入不可中断睡眠态 xff0c 挂起在等待队列上 参数 xff1a p 等待队列头 返回 xff1a xff08 无 xff09
  • 关于Windows系统环境变量的引用问题

    做Leap Motion开发时 xff0c 新建了LEAP SDK的系统环境变量 xff0c 按照官方SDK文档中说明的 xff0c 在工程中引入 LEAP SDK include 之前半年的时间里都是这样做的 xff0c 没有任何问题 x
  • 深入理解Linux内核--信号

    信号用于在用户态进程间通信 内核也用信号通知进程系统所发生的事情 1 信号的作用 信号 signal 是很短的消息 xff0c 可以被发送到一个进程或一组进程 发送给进程的唯一信息通常是一个数 xff0c 以此来标识信号 使用信号的两个主要
  • 进程上下文与中断上下文

    处理器总处于以下状态中的一种 xff1a xff11 内核 态 xff0c 运行于进程 上下文 xff0c 内核代表进程运行于内核空间 xff12 内核态 xff0c 运行于中断上下文 xff0c 内核代表硬件运行于内核空间 xff13 用
  • 进程上下文VS中断上下文

    内核空间和用户空间是现代操作 系统的两种工作模式 xff0c 内核模块运行在内核空间 xff0c 而用户态应用程序运行在用户空间 它们代表不同的级别 xff0c 而对系统资源具有不同的访问权限 内核模块运行在最高级别 xff08 内核态 x
  • 中断不可睡眠的一些理解

    一 LINUX中到是有中断还没有完全返回就调用schedule 而睡眠过去的例子 可以猜是哪里 我觉得 xff0c 中断和异常不同 xff0c 中断是异步的 xff0c 异常和系统调用是同步的 异常比如缺页异常发生时 xff0c 当前任务在
  • kmalloc和vmalloc

  • linux内核中内存相关的操作函数

    1 kmalloc kfree static always inline void kmalloc size t size gfp t flags 内核空间申请指定大小的内存区域 xff0c 返回内核空间虚拟地址 在函数实现中 xff0c
  • Oracle安全:SCN可能最大值与耗尽问题Oracle安全:SCN可能最大值与耗尽问题

    SCN的问题一旦出现 xff0c 使得数据库的一切事务停止 xff0c 由于SCN不能后退 xff0c 所以数据库必须重建 xff0c 才能够重用 在2012年第一季度的CPU补丁中 xff0c 包含了一个关于SCN修正的重要变更 xff0
  • Linux内核 申请和释放内存流程

    1 内核初始化 xff1a 内核建立好内核页目录页表数据库 xff0c 假设物理内存大小为len xff0c 则建立了 3G 3G 43 len 0 len 这样的虚地址vaddr和物理地址paddr的线性对应关系 xff1b 内核建立一个