通俗解释进程-科学家做蛋糕 科学家做蛋糕 然后女儿被蜜蜂蛰了 进程表–在内核 内存管理 经典 老式 管理方法: 基址寄存器(程序开始的地方) + 界限寄存器(程序长度) 空闲内存管理...每个页框有一个编号,即“页框号”(页框号=页帧号=内存块号=物理块号=物理页号),页框号从0开始 将进程的逻辑地址空间也分为与页框大小相等的一个个部分,每个部分称为一个“页”或“页面”。...每个页面也有一个编号,即“页号”,页号也是从0开始。 操作系统以页框为单位为各个进程分配内存空间。进程的每个页面分别放入一个页框中。也就是说,进程的页面与内存的页框有一一对应的关系。...各个页面不必连续存放,可以放到不相邻的各个页框中。 重要的数据结构——页表 为了能知道进程的每个页面在内存中存放的位置,操作系统要为每个进程建立一张页表。...注:页表通常存在PCB中 一个进程对应一张页表 进程的每个页面对应一个页表项 每个页表项由“页号”和“块号”组成 页表记录进程页面和实际存放的内存块之间的映射关系
前面已经分析了内核页表的准备工作以及内核低端内存页表的建立,接着回到init_mem_mapping()中,低端内存页表建立后紧随着还有一个函数early_ioremap_page_table_range_init...回到page_table_range_init(),其中one_md_table_init()是用于当pgd入参为空时,申请新物理页作为页中间目录的,但是此次仅分析x86非PAE环境的情况,不存在页中间目录...,创建页表并使其指向被创建的页表。...为了避免前期可能对固定映射区已经分配了页表项,基于临时内核映射区间要求页表连续性的保证,所以在此重新申请连续的页表空间将原页表内容拷贝至此。...至此,内核页表建立完毕。
前面已经分析过了Intel的内存映射和linux的基本使用情况,已知head_32.S仅是建立临时页表,内核还是要建立内核页表,做到全面映射的。...建立内核页表前奏,了解两个很关键的变量: max_pfn:最大物理内存页面帧号; max_low_pfn:低端内存区(直接映射空间区的内存)的最大可用页帧号; max_pfn 的值来自setup_arch...Linux是一个支持多硬件平台的操作系统,各种硬件芯片的分页并非固定的2级(页全局目录和页表),仅仅Intel处理器而言,就存在3级的情况(页全局目录、页中间目录和页表),而到了64位系统的时候就成了4...所以Linux为了保持良好的兼容性和移植性,系统设计成了以下的4级分页模型,根据平台环境和配置的情况,通过将页上级目录和页中间目录的索引位设置为0,从而隐藏了页三级目录和页中间目录的存在。...此外还有一个准备操作,在setup_arch()函数中调用的页表缓冲区申请操作: early_alloc_pgt_buf(): 【file:/arch/x86/mm/init.c】 void __init
前面的前奏已经分析介绍了建立内核页表相关变量的设置准备,接下来转入正题分析内核页表的建立。...建立内核页表的关键函数init_mem_mapping(): 【file:/arch/x86/mm/init.c】 void __init init_mem_mapping(void) { unsigned...最终建立内核页表的同时,完成内存映射。...,然后开始建立页表,其关键函数是init_range_memory_mapping(),该函数的实现: 【file:/arch/x86/mm/init.c】 /* * We need to iterate...至此,内核低端内存页表建立完毕。
1.页表基本概念 2.进程是如何和“页表”进行联系? 3.每个进程都有页表,页表在“进程切换”如何跟踪 三.地址空间&页表的作用机理 1.地址空间&页表的基本原理 2....【页表实验5】缺页中断(进程地址空间建立“进程管理”与“内存管理”的联系)【全流程配图详解】(重点) 一.什么是进程地址空间?...进程各种访问寻址的前提, 一定是它在cpu上运行 cpu上有个 特殊寄存器cr3 ,他会保存页表地址,物理地址(页表地址会保存在进程的上下文当中) 3.每个进程都有页表,页表在“进程切换”如何跟踪...【页表实验5】缺页中断(进程地址空间建立“进程管理”与“内存管理”的联系)【全流程配图详解】(重点) 全流程讲解: 当前有个进程开始访问,通过cpu得到了页表的地址,访问页表,想找到物理地址...1 结论:进程地址空间建立进程管理与内存管理的联系
可能是其他同学在下载或者上传数据,所以需要看到底是哪个进程。 这时候使用 iftop, vnstat 等命令不能看出具体是哪个进程占用,因为它们常用来统计和监控网卡流量。
在数据同步时提到以前的博客,在每个站点都会有创建触发器对于每个工作表,当运行CRUD。...触发器的任务就是对其进行操作sql声明拼接成一个字符串,并存储在表中synchro_tb_operate_log中,假设触发器运行出现异常,则将其异常信息保存在还有一个表中:SYNCHRO_DATA_EXCEP_LOG...TRIGGER_ITEM_REC" after insert or update or delete on ITEM_REC FOR EACH ROW /** HEAD * @name 项目记录表触发器...形成ddl语句插入同步表中 * @version 1.0.0 * @author Tang * @create-date 2014-07-01 */ declare v_sql nvarchar2...YYYY-MM-DD HH24:MI:SS')); end if; exception when others then--假设运行过程中出现异常,则将异常信息插入到SYNCHRO_DATA_EXCEP_LOG表中
1、PGD: Page Global Directory Linux系统中每个进程对应用户空间的pgd是不一样的,但是linux内核 的pgd是一样的。...USER_PTRS_PER_PGD, swapper_pg_dir +USER_PTRS_PER_PGD, (PTRS_PER_PGD - USER_PTRS_PER_PGD) * sizeof(pgd_t)) 这样一来,每个进程的页面目录就分成了两部分...可以看出Linux系统中每个进程的页面目录的第二部分是相同的,所以从进程的角度来看,每个进程有4G字节的虚拟空间,较低的3G字节是自己的用户空间,最高的1G字节则为与所有进程以及内核共享的系统空间。...每个进程有它自己的PGD( Page Global Directory),它是一个物理页,并包含一个pgd_t数组。...每一个页表项指向一个页框,页框就是真正的物理内存页。
,造成每个进程都认为自己拥有所有虚拟内存的错觉;通过页表给一段内存设置只读属性,那么就不容许修改这段内存内容,从而保护了这段内存不被改写;对应用户进程地址空间映射的物理内存,内核可以很方便的进行页面迁移和页面交换...1)使用一级页表结构优劣: 优势: 只需要2次访问内存(一次访问页表,一次访问数据),效率高,实现简单 劣势: 需要连续的大块内存存放每个进程的页表(如32位系统每个进程需要4M页表),浪费内存,虚拟内存越大页表越大...2)Linux内核 填写页表,将页表基地址告诉mmu 内核初始化建立内核页表,实现缺页异常等机制为用户任务按需分配并映射页表。 当然,内核也可以遍历页表,如缺页异常时遍历进程页表。 10....2)用户页表填充 访问时缺页填充: 用户进程访问已经申请的虚拟内存时,发生缺页,缺页处理程序中为进程分配各级页表等物理页并建立页表映射关系。...12.页表遍历过程 下面以arm64处理器架构多级页表遍历作为结束(使用4级页表,页大小为4K): Linux内核中 可以将页表扩展到5级,分别是页全局目录(Page Global Directory,
缺页异常,对于进程申请的内存,并不需要在其申请内存时即建立地址转换映射表,同时分配对应的物理空间,而是在进程真正访问内存地址时,MMU上报缺页异常再分配对应的物理空间。...开篇我们提到,进程的虚拟地址到物理地址的转换是不同的,所以每个进程的映射关系也是不同的,就是说每个进程都需要4MB的空间来存储页表。如果操作系统运行100个进程,则需要400MB空间。...每个进程都拥有自己独立的地址空间,进程切换时地址空间也会切换。不同进程都拥有自己的一套页表,因而即使两个进程虚拟地址相同,映射的物理地址也是不同的。...而Linux有一个三层的页表结构,可以很容易地将其包装成适合两层的页表结构—只使用PGD和PTE。但是,Linux还要求每个页面有一个“PTE”表,而且至少要有一个“dirty”位。...因此,在这里稍微调整了实现—告诉Linux在第一级有2048个条目,每个都是8字节。二级页表包含两个连续排列的硬件PTE表项,前面的表项是包含Linux需要的状态信息的Linux PTE。
如果你看过 Linux 内核相关书籍,一定对下面这张图又熟悉、又恐惧: 这是 Linux 系统中,页处理单元的多级页表查询方式。...我们举了这样一个示例: 假设实际的物理内存是1 GB; 用户程序文件在硬盘上的长度是20 MB; 操作系统把用户程序加载到内存中时,从 0x4000_0000 的虚拟内存地址处开始存放; 操作系统读取程序结束后,为所有的地址构造好了页目录和页表...; 如下图所示: 页目录和页表的每一个有效表项中,存储的地址都是一个个实实在在的物理页的前 20 位(因为一个物理页的长度固定是 4KB,在分配时都是对齐的,末尾的 12 位全部为 0)。...详细的讨论过程,请参考上一篇文章:Linux从头学15:【页目录和页表】-理论 + 实例 + 图文的最完全、最接地气详解!。...例如:mov [0xFFFF_4000], xxxx 以上就是操作系统在操作页目录自身时,所采取的策略。 具体到每个操作系统来说,可能稍微有差别,但是其中的道理都是差不多的。
目录 前言 Intel四级页表 实操寻址 获取cr3 获取PGD 获取PUD 获取PMD 获取PTE 获取内容 最后 ---- 前言 Linux四级页表的作用主要就是地址映射, 将逻辑地址映射到物理地址...很多时候, 有些地方想不明白就可以查看实际物理地址进行分析. ---- Intel 四级页表 其实很多设计的根源或者说原因都来自于CPU的设计, OS很多时候都是辅助CPU....Linux的四级页表就是依据CPU的四级页表来设计的. 这里主要说的就是Intel x64页面大小为4KB的情况, 如图所示: ?...在Linux当中, 第一级页表称为PGD, 当然是有历史原因的, 可以自行google. 所以Linux的四级页表分别是PGD -> PUD -> PMD -> PTE. ?...因为每个单元是64-bits因此需要在序号基础上乘以8获得地址.
以典型的4K页和48位虚拟地址为例,整个内核空间的虚拟地址分布如下: ?...我们看看这种情况下的页表,我们既可以用最终的【20:12】对应的PTE映射项,以4K为单位,进行虚拟地址到物理地址的映射;又可以以【29:21】对应的PMD映射项,以2M为单位,进行虚拟地址到物理地址的映射...所以,即便我们在内核空间进行PMD映射,里面的每个蓝色圆圈(一个4K页),还是可以被单独分配的,这种分配可以是kmalloc、vmalloc,用户态的malloc等。...我在内核启动参数加的rodata=0实际上是让rodata_full为false。如果我把这个kernel启动选项去掉,我得到的内核页表是完全不一样,线性映射区也全部是PTE映射: ?...在这个patchset中,它就需要拆分vmemmap的PMD映射为PTE映射: ? 这个patchset的原理建立在,当内核以4KB分页的时候,每个page需要64字节的page struct。
作 者:道哥,10+年嵌入式开发老兵,专注于:C/C++、嵌入式、Linux。...关注下方公众号,回复【书籍】,获取 Linux、嵌入式领域经典书籍;回复【PDF】,获取所有原创文章( PDF 格式)。...在 32 位系统中,它使用了多达4MB的物理内存空间(每个表项4个字节,一共有4G/4K个表项)。 为了解决这个问题,x86处理器使用了两级转换:页目录和页表。...,1024(每个表中的表项个数) * 1024(表的个数),仍然可以覆盖4GB的物理内存空间。...这个寄存器中,保存了当前正在执行的那个任务的页目录地址。 每个任务(程序)都有自己的页目录和页表,页目录表的地址被记录在任务的TSS段中。
再次访问匿名页时通过换出页标识符即可将所需的数据页从交换分区换入再建立页表映射即可。 而对于文件页,如果是“干净的”文件页,是可以直接丢弃回收。...由于文件页有后备文件支持,再次访问文件页时,将所需的数据页从文件中读取到内存建立页表映射即可。 图:反向映射应用之页面迁移 第二个场景是页面迁移,页面迁移在内核的CMA、内存碎片整理等被广泛使用。...迁移过程中,进程再次访问会发生swap缺页异常,异常处理中判断为迁移类型表项就会是进程睡眠等待迁移完成。...图:反向映射应用之脏页跟踪(1) 图:反向映射应用之脏页跟踪(2) 第三个场景是脏页跟踪,对于共享的文件页,由于文件页被多个进程共享,linux内核通过页表项的“脏”标记跟踪页面为脏。...再次访问时,发生写实复制缺页异常,异常处理中再次设置页表项为脏、可写,从而跟踪了脏页。 图:反向映射应用场景之访问跟踪 还有个场景是访问跟踪,linux内核通过页表项的“访问”标记跟踪页面被访问。
页表项(Page Table Entry)大小为4字节,存储一个物理内存页起始地址。每个页表同样占用4K内存,可以存储1024个物理内存页起始地址。...3. 1024个页表,每个页表1024个物理内存页起始地址,合计就是1M个地址,每个地址指向的物理内存页大小为4KB,合计为4GB。 4....再看看目录表和页表这2种数据结构占用的空间会有多少。目录表固定只有4KB。而页表呢?由于最多有1024个页表,每个页表占用4KB,因此页表最多占用4MB内存。...同时Linux不会为进程一次性建立那么大的页表,只有进程在分配和访问内存时,操作系统才会为进程建立相应地址的映射。 这里只描述了最简单情况下的分页映射。实际上页表目录连同页表一共有四级。...从AWR报告来看,有300个左右的会话,那么这300个连接的页表会达到7200MB,只不过并不是每个进程都会访问到SGA中所有的内存。
下面闲话少说,开始本篇的内容——进程的内存消耗和泄漏 进程的虚拟地址空间VMA(Virtual Memory Area) 在linux操作系统中,每个进程都通过一个task_struct的结构体描叙,每个进程的地址空间都通过一个...上图中,task_struct中的mm_struct就代表进程的整个内存资源,mm_struct中的pgd为页表,mmap指针指向的vm_area_struct链表的每一个节点就代表进程的一个虚拟地址空间...如,执行代码段时会发生缺页,Linux申请1页内存,并从硬盘读取出代码段,此时产生了IO操作,为major主缺页。...如,执行代码段时会发生缺页,Linux申请1页内存,并从硬盘读取出代码段,此时产生了IO操作,为major主缺页。 ?...(此图来源于宋宝华老师) 1044,1045,1054三个进程,每个进程都有一个页表,对应其虚拟地址如何向real memory上去转换。
下面闲话少说,开始本篇的内容——进程的内存消耗和泄漏 进程的虚拟地址空间VMA(Virtual Memory Area) 在linux操作系统中,每个进程都通过一个task_struct的结构体描叙,每个进程的地址空间都通过一个...上图中,task_struct中的mm_struct就代表进程的整个内存资源,mm_struct中的pgd为页表,mmap指针指向的vm_area_struct链表的每一个节点就代表进程的一个虚拟地址空间...如,执行代码段时会发生缺页,Linux申请1页内存,并从硬盘读取出代码段,此时产生了IO操作,为major主缺页。...综上,page fault后,Linux会查VMA,也会比对VMA中和页表中的权限,体现出VMA的重要作用。...1044,1045,1054三个进程,每个进程都有一个页表,对应其虚拟地址如何向real memory上去转换。 process 1044的1,2,3都在虚拟地址空间,所以其VSS=1+2+3。
在Linux内核中,无论如何切换进程,内核地址空间转换到物理地址的关系是永远不变的,主要原因是内核地址空间在所有进程中是共享的。这种设计有几个关键点: 1....内核地址空间共享 在Linux操作系统中,每个进程都有自己独立的用户空间地址范围,但内核空间地址范围对所有进程是共享的。...具体来说,每个进程的地址空间被划分为用户空间和内核空间两部分: 用户空间:每个进程有独立的用户空间地址,通常在较低的地址范围。 内核空间:所有进程共享相同的内核空间地址,通常在较高的地址范围。...页表和地址转换 在x86架构中,内核和用户空间的地址转换通过页表来实现。每个进程都有自己的页表用于转换用户空间地址到物理地址。然而,所有进程共享同一个内核空间,因此这些页表中内核空间部分是相同的。...即使进程切换,也不需要重新建立内核地址空间的映射,从而提高了系统效率和稳定性。
,因此在linux 0.11中多个进程可以共享一套页表。...但是,对于现代32操作系统而言,每个进程都会单独占有4G虚拟内存,各个进程对应的页表是会产生重叠的,因此每个进程需要有自己的段表和页表。...这里说的地址都是当前进程享有的一块完整的虚拟内存中的地址 内核为系统中的每个进程维护一个单独的任务结构(task_struct)。...pgd指向一级页表的基址(当内核运行这个进程时,pgd会被存放在CR3控制寄存器,也就是页表基址寄存器中),mmap指向一个vm_area_structs的链表,其中每个vm_area_structs都描述了当前虚拟地址空间的一个区域...,建立页表,该过程在mmap函数中并未实现,此时只是创建了映射关系,并不将任何文件数据拷贝至主存中,真正的数据拷贝是通过进程发起读写操作时 进程访问该映射空间,实现文件内容到物理内存的数据拷贝,当进程读写访问该映射地址时
领取专属 10元无门槛券
手把手带您无忧上云