一、linux用户态内核态内存结构
对于32位的linux操作系统,系统为每个进程分配0~4G的内存空间,而64位系统则更大:

linux内存空间地址范围

可见Linux的内存分配规则:

二、总体分配规则

1、用户态在低地址,内核态在高地址。

2、 64位的系统,目前一般使用了48位。用户态高16位都是0, 内核态高16位一直是FFFF。 都用剩下的48位来表示128T。1T==1024*1024*1024*1024。 剩下的8位直接上也只用了7位, 第48位来表示是内核空间还是用户空间。加一起 48位表示的就是128T。

其中,0x0000000000000000~0x00007fffffffffff 表示用户空间, 0xFFFF800000000000~ 0xFFFFFFFFFFFFFFFF 表示内核空间,共提供 256TB(2^48) 的寻址空间。
     这两个区间的特点是,第 47 位与 48~63 位相同,若这些位为 0 表示用户空间,否则表示内核空间。所以上面那个话64位的内存分布图有点问题。用户态128T的最高地址不对。

三、用户空间分配规则

1、用户空间堆申请空间往上涨,栈申请空间往下涨,栈的地址肯定比堆的地址高。 然后栈和堆中间还有一段区域用来共享:文件映射, mmap使用。

文件映射,用于映射共享库等程序运行必须的文件,同时该区域可用于申请较大的内存

2、用户空间运行时动态申请内存

malloc的分配内存有两个系统调用,一个brk,一个mmap,brk是将.data的最高地址指针_edata往高地址走,mmap则是在进程的虚拟地址空间(在堆和栈之间的内存映射区域)找一块空间。这两种都是没有实际分配物理内存,只有当真正使用的时候才发生缺页中断,分配物理内存。

一般情况下,使用malloc,如果小于128k,则使用brk分配,如果大于128k,则使用mmap在堆和栈之间找一个空闲空间分配。

3、用户空间虚拟地址中各段内容

A.正文段。这是由cpu执行的机器指令部分。通常,正文段是可共享的,所以即使是经常执行的程序(如文本编辑程序、C编译程序、shell等)在存储器中也只需要有一个副本,另外,正文段常常是只读的,以防止程序由于意外事故而修改器自身的指令。

B.初始化数据段。通常将此段称为数据段,它包含了程序中需赋初值的变量。例如,C程序中任何函数之外的说明:
int maxcount = 99;(全局变量)

C.非初始化数据段。通常将此段称为bss段,这一名称来源于早期汇编程序的一个操作,意思是"block started by symbol",在程序开始执行之前,内核将此段初始化为0。函数外的说明:
long  sum[1000];
使此变量存放在非初始化数据段中。 注意这个地方初始化和非初始化的区别。

D.栈。自动变量以及每次函数调用时所需保存的信息都存放在此段中。每次函数调用时,其返回地址、以及调用者的环境信息(例如某些机器寄存器)都存放在栈中。然后,新被调用的函数在栈上为其自动和临时变量分配存储空间。通过以这种方式使用栈,C函数可以递归调用。

E.堆。通常在堆中进行动态存储分配。由于历史上形成的惯例,堆位于非初始化数据段顶和栈底之间。

四、内核空间分配规则

1、内核空间结构

内核空间分为几大区域

直接映射区:分配的虚拟地址映射到连续的物理地址上

动态映射区:分配的虚拟地址映射到物理地址是不连续的

永久内存映射区:

固定映射区:虚拟地址是固定的,而被映射的物理地址并不固定。采用固定虚拟地址的好处是它相当于一个指针常量(常量的值在编译时确定),指向物理地址,如果虚拟地址不固定,则相当于一个指针变量。指针常量相比指针变量的好处是可以减少一次内存访问,因为指针变量需要通过内存访问才可以获得指针本身的值。

2、直接映射区

在3GB~(3GB+896MB)这段直接映射区,包含了内核初始化页表swapper_pg_dir,内核镜像等。内核也是由一个elf文件(比如vmlinux)加载启动的,加载后也有text段,data段,bss段等。可通过cat /proc/iomem命令查看kernel的text段,data段和bss段的内存分布。

normal memory区也属于直接映射区,用于kmalloc()的内存分配,kmalloc()返回的是虚拟地址,但分到的内存在物理地址上是连续的。

2、动态映射区

动态映射区即上图vmalloc area区,对应下图VMALLOC_START和VMALLOC_END之间的区域,动态内存映射区和直接映射区(直接映射的物理内存)之间有8MB的间隔。这部分间隔不作任何地址映射,相当于一个空洞,主要用做安全保护,防止不正确的越界内存访问,因为此处没有进行任何形式的映射,如果进入到空洞地带,将会触发处理器产生一个异常。

动态映射区主要供vmalloc()分配内存,同kmalloc()相比,vmalloc()分配的内存只能保证在虚拟地址上连续,不能保证在物理地址上连续。在物理地址上连续有什么好处呢?

  • 可以更好的根据空间局部性原理利用cache,增加数据访问的速度。
  • 由于kmalloc()基于的是直接映射,其虚拟地址和物理地址之间是一个固定的偏移,因此可以利用既有的内核页表,而不需要为新的地址增加新的page table entries,因此其分配速度也比vmalloc()更快。
  • 因为物理地址不连续,通过vmalloc()获得的每个page需要单独映射,而TLB资源很有限,因此这将比直接映射造成更严重的TLB thrashing问题。

用户空间的进程通过malloc()分配内存时,获得的只是虚拟地址的使用权,要等到真正往这块内存写数据了,才会获得对应的物理页面,而且是用多少给多少,而不是要多少给多少。内核空间的vmalloc()不一样,申请的物理内存立刻满足。

五、真实物理内存

网上有ZONE_DMA、ZONE_NORMAL、ZONE_HIGMEM的说法,主要针对真实物理内存的分区

参考:

linux 内存空间(三) 内存地址范围和例子

linux中的内核地址空间

https://www.cnblogs.com/antidogmatist/p/16966897.html

linux虚拟内存结构相关推荐

  1. 每天一个linux命令(23):Linux 目录结构

    对于每一个Linux学习者来说,了解Linux文件系统的目录结构,是学好Linux的至关重要的一步.,深入了解linux文件目录结构的标准和每个目录的详细功能,对于我们用好linux系统只管重要,下面 ...

  2. [转]十问 Linux 虚拟内存管理 (glibc)

    最近在做 MySQL 版本升级时( 5.1->5.5 ) , 发现了 mysqld 疑似"内存泄露"现象,但通过 valgrind 等工具检测后,并没发现类似的问题.因此,需 ...

  3. linux 进程管理 ppt,Linux内核结构与进程管理.ppt

    Linux内核结构与进程管理.ppt Linux 内核结构与进程管理,Linux系统结构Linux kernel 开放源代码的linux操作系统内核,目前版本为2.6,Linux内核组成1. 进程调度 ...

  4. 文件系统(文件系统目录结构、磁盘分区、虚拟文件系统)、linux内核结构框图

    什么是文件系统? 常规认知就是根目录下那些文件,但其实并不是那样.文件系统是操作系统用于明确存储设备(常见的是磁盘,也有基于NAND Flash的固态硬盘)或分区上的文件的方法和数据结构:即在存储设备 ...

  5. linux目录结构与功能_深入理解linux系统的目录结构(总结的非常详细)

    对于每一个Linux学习者来说,了解Linux文件系统的目录结构,是学好Linux的至关重要的一步.,深入了解linux文件目录结构的标准和每个目录的详细功能,对于我们用好linux系统只管重要,下面 ...

  6. Linux虚拟内存管理 | 虚拟地址与物理地址映射、段错误SIGSEGV

    目录 x86 内存寻址 x86 分页机制 虚拟内存地址管理 虚拟地址与物理地址映射 - do_page_fault() 推荐阅读 Linux的内存管理分为 虚拟内存管理 和 物理内存管理,本文主要介绍 ...

  7. 操作系统——Linux 虚拟内存和物理内存的理解

    虚拟内存: 第一层理解 1..每个进程都有自己独立的4G内存空间,各个进程的内存空间具有类似的结构: 2.一个新进程建立的时候,将会建立起自己的内存空间,此进程的数据,代码等从磁盘拷贝到自己的进程空间 ...

  8. 认识linux内核结构

    linux内核结构 用户级 函数库 :提供了应用程序支配内核干活的接口 内核级 Linux内核主要由五个子系统组成:进程调度,内存管理,虚拟文件系统,网络接口,进程间通信. 1.进程调度(Proces ...

  9. 一步一图带你深入理解 Linux 虚拟内存管理

    从本文开始我们就正式开启了 Linux 内核内存管理子系统源码解析系列,笔者还是会秉承之前系列文章的风格,采用一步一图的方式先是详细介绍相关原理,在保证大家清晰理解原理的基础上,我们再来一步一步的解析 ...

最新文章

  1. Go语言学习笔记(一)Let's 干吧
  2. 中南财经政法大学计算机考研难吗,中南财经政法大学考研难吗(考研难度分析)...
  3. TF之BN:BN算法对多层中的每层神经网络加快学习QuadraticFunction_InputData+Histogram+BN的Error_curve
  4. 【文本描述增强】标准屏幕字段文本描述更改增强
  5. HTML+CSS+JavaScript复习笔记持更(五)——CSS选择器
  6. 消息消费端的确认机制
  7. android 手动签名apk,记录手动签名APK的过程
  8. Django项目功能执行逻辑流程图之用户页面信息展示和添加
  9. FCN-Fully Convolutional Networks
  10. python的学习笔记/002-5(2018-5-21)
  11. 想和人脑一样智能? IBM 的芯片级模仿才是关键
  12. 强类型视图 后台拿不到数据_SAP开发-ABAP数据字典(视图)
  13. python 新式类和旧式类
  14. 路由器第三方固件的刷入与调试
  15. 【树形DP+DFS】Gym 100962J - Jimi Hendrix
  16. 【css】css实现果冻盒子加载动画
  17. 纯CSS实现的3D翻页效果
  18. DRV8825 TB8825 最佳线路图布局
  19. javascript jc脚本语言
  20. error uploading crisocket: timed out waiting for the conditionswapoff -a # will turn off the swap

热门文章

  1. 系统吞吐量(TPS)、用户并发量、性能测试概念和公式
  2. opend和open的区别_open和close的用法请大家说说close和closed的区别 还有open和opend的区别...
  3. 可以随处沉浸的音频体验——飞利浦Fidelio L3的惊艳表现
  4. 《AutoCAD全套园林图纸绘制自学手册》一第2章 AutoCAD 2013入门2.1 操作界面
  5. 100个Python实战项目(六)15 行代码进行人脸检测(使用Python 和 OpenCV)
  6. python 的高级特性:函数式编程,lambda表达式,装饰器
  7. 怪兽充电、竹芒、小电:蜕变
  8. 无线路由的软件测试,软件测试中无线路由器安全功能测试
  9. MySQL - 索引类型详解
  10. A 股指数成分数据 API 数据接口