文档章节

Linux内存布局

linuxprobe16
 linuxprobe16
发布于 09/21 07:52
字数 1526
阅读 7
收藏 0
今天这篇文章主要是我之前看Linux内核相关知识和博客Gustavo Duarte中。我主要是看了这篇博客,并且结合之前的知识,对内存管理的的理解又上升了一个档次。所以想通过这篇文章总结下。

我们先来看下Linux内存布局,此图比我之前写的那篇文章写的布局更详细

Linux内存布局Linux内存布局

在linux中,每一个进程都被抽象为task_struct结构体,称为进程描述符,存储着进程

各方面的信息;例如打开的文件,信号以及内存等等;然后task_struct的一个属性mm_struct管理着进程的所有虚拟内存,称为内存描述符。在mm_struct结构体中,存储着进程各个内存段的开始以及结尾,如上图所示;这个进程使用的物理内存,即常驻内存RSS页数,这个内存使用的虚拟地址空间VSZ页数,还有这个进程虚拟内存区域集合和页表。

从上面这个图可以看出,进程是有代码段Text segment,数据段(已初始化的全局,静态变量),BSS段(未初始化的全局,静态变量),堆,内存映射区以及栈;

每一块虚拟内存区(VMA)都是由一块连续的虚拟地址组成,这些地址从不覆盖。一个vm_area_struct实例描述了一块内存区域,包括这块内存区域的开始以及结尾地址;flags标志决定了这块内存的访问权限和行为;vm_file决定这块内存是由哪个文件映射的,如果没有文件映射,则这块内存为匿名的(anonymous)。上述图中提到的每个内存段,都对应于一个vm_area_struct结构。如下图所示

Linux内存布局Linux内存布局

上图即为/bin/gonzo进程的内存布局。程序的二进制文件映射到代码段和数据段,代码段为只读只执行,不可更改;全局以及静态的未初始化的变量映射到BSS段,为匿名映射,堆和栈也是匿名映射,因为没有相应的文件映射;内存映射区可以映射共享库,映射文件以及匿名映射,所以这块内存段可以是文件映射也可以是匿名映射。而且不同的文件,映射到不同的vm_area_struct区。

这些vm_area_struct集合存储在mm_struct中的一个单向链表和红黑树中;当输出/proc/pid/maps文件时,只需要遍历这个链表即可。红黑树主要是为了快速定位到某一个内存块,红黑树的根存储在mm_rb域。

之前介绍过,线性地址需要通过页表才能转换为物理地址。每个进程的内存描述符也保存了这个进程页表指针pgd,每一块虚拟内存页都和页表的某一项对应。

虚拟内存是不存储任何数据的,它只是将地址空间映射到物理内存。物理内存有内核伙伴系统分配,如果一块物理内存没有被映射,就可以被伙伴系统分配给虚拟内存。刚分配的物理内存叶框可能是匿名的,存储进程数据,也可能是也缓存,存储文件或块设备的数据。一块虚拟内存vm_area_struct块是由连续的虚拟内存页组成的,而这些虚拟内存块映射的物理内存却不一定连续,如下图所示:

Linux内存布局Linux内存布局

如上图所示,有三个页映射到物理内存,还有两个页没有映射,所以常驻内存RSS为12kb,而虚拟内存大小为20kb。对于有映射到物理内存的三个页的页表项PTE的Present标志设为1,而两个没有映射物理内存的虚拟内存页表项的Present位清除。所以这时访问那两块内存,则会导致异常缺页。

vma就像应用程序和内核的一个契约。当应用程序申请内存或者文件映射时,内核先响应这个请求,分配或更新虚拟内存;但是这些虚拟内存并没有映射到真实的物理内存。而是等到内存访问产生一个内存异常缺页时才真正映射物理内存。即当访问没有映射的虚拟内存时,由于页表项的Present位没有被设置,所以此时会产生一个缺页异常。vma记录和页表项两个在解决内存缺页,释放内存以及内存swap out都起着重要的作用。下面图展示了上述情况:

Linux内存布局Linux内存布局

1、一开始堆中只有8kb的内存,而且都已经映射到物理内存;

2、当调用brk()函数扩展堆时,新的页是没有映射到物理内存的,

3、当处理器需要访问一个地址,而且这个地址在上述刚分配的虚拟内存中,这时产生一个缺页异常;

4、这时进程向伙伴系统申请一页的物理内存,映射到那块虚拟内存上,并添加页表项,设置Present位.

自此,这个内存管理暂时就说到这。总结下:

1、Linux进程的内存布局的每个段都是有一个vm_area_struct,而这个实例是由连续的虚拟内存地址组成;

2、当请求内存时,先是扩展vm_area_struct或者新分配一个vm_area_struct,但是并不映射物理内存,只有等到访问这块内存时,产生缺页异常,内核才分配物理内存。

本文地址:https://www.linuxprobe.com/linux-memory-layout.html

本文转载自:https://www.linuxprobe.com/linux-memory-layout.html

共有 人打赏支持
linuxprobe16
粉丝 11
博文 777
码字总数 171013
作品 0
河东
浅谈 C 字符串数组的内存布局

首先感谢秋豪大佬对文章的校对以及耐心的指导 先献上我的膝盖 or2 整理了四种常见的使用 C 语言字符串数组的形式 分别对这以下几种的内存布局进行分析 默认读者已经有了以下基本知识: C 语言...

王一航
05/05
0
0
VMware10自定义安装Redhat 6.3(全)

Redhat公司Linux发行版中版本号小于4的表示公测版。 可以用来学习,但不适合用在生产上,比如 6.1、6.2、6.3 。 比较老的版本也建议用在生产上,Redhat不再 release(发布)版本意味着 bug修复...

翻船全靠浪
2015/06/18
0
0
移植Linux到SAMSUNG S3C2410开发板

【S3C2410简介】 S3C2410装备有SAMSUNG产ARM920T核、一体化16kB Cache/MMU能轻松奔跑Linux。 该板资源如下: (1) CPU : ARM920T 工作频率为 200MHz 。 (2) Flash : 16MB (3) SDRAM : 64MB SD...

os9330
2013/09/07
0
0
Centos Linux 下查看服务器信息的方法

经常有客户咨询云志互联查看服务器一些硬件配置的方法,下面将以Centos为例,将各种信息的查看方法与用户分享。本教程使用于Centos,Debian等各Linux发行版 查看服务器CPU型号 grep "model na...

光石头
2011/06/23
0
0
嵌入式软件环境构建:uboot、kernel、rootfs、app布局

嵌入式开发涉及硬件和软件两部分,个人目前主要是做嵌入式软件部分,使用uboot+linux的整体方案。这里所说的“嵌入式软件环境”,不是指宿主机上的嵌入式开发环境,而是指目标机中的运行软件...

水海云
2013/02/01
0
2

没有更多内容

加载失败,请刷新页面

加载更多

Shell特殊符号总结以及cut,sort,wc,uniq,tee,tr,split命令

特殊符号总结一 * 任意个任意字符 ? 任意一个字符 # 注释字符 \ 脱义字符 | 管道符 # #号后的备注被忽略[root@centos01 ~]# ls a.txt # 备注 a.txt[root@centos01 ~]# a=1[root@centos01...

野雪球
27分钟前
1
0
OSChina 周二乱弹 —— 程序员圣衣

Osc乱弹歌单(2018)请戳(这里) 【今日歌曲】 @达尔文:分享Skeeter Davis的单曲《The End of the World》 《The End of the World》- Skeeter Davis 手机党少年们想听歌,请使劲儿戳(这里...

小小编辑
42分钟前
4
0
[ python import module ] 导入模块

import moudle_name ----> import module_name.py ---> import module_name.py文件路径 -----> sys.path (这里进行查找文件) # from app.web import Personimport app.web.Person as Pe......

_______-
昨天
3
0
Redis性能问题排查解决手册

一、性能相关的数据指标 通过Redis-cli命令行界面访问到Redis服务器,然后使用info命令获取所有与Redis服务相关的信息。通过这些信息来分析文章后面提到的一些性能指标。 nfo命令输出的数据可...

IT--小哥
昨天
1
0
mixin混入

①新建mixin.js文件 const mixin = { methods: { /** * 分页公共方法 */ handleSizeChange(val) { this.pageData.size = val; this.query(); }, hand......

不负好时光
昨天
2
0

没有更多内容

加载失败,请刷新页面

加载更多

返回顶部
顶部