文档章节

进程的虚拟地址空间分布

o
 osc_fmg49rzg
发布于 2019/03/22 13:35
字数 1271
阅读 3
收藏 0

精选30+云产品,助力企业轻松上云!>>>

1)在linux下内存分配是以页为单位的,而页是通过段管理

2)一个linux进程的虚拟地址空间分布如上图所示,分为用户空间和内核空间,对于一个32位操作系统来说,4GB的空间分成两部分,低地址的0~3G给用户空间,高地址的3G~4G给内核空间

1.用户空间

1.1只读数据段(也叫常量段,.rodata,Read Only之意,未在图中标出)

1)存放只读数据:字符串常量(如"hello")和const修饰的全局变量

2)不是所有的只读数据都是放在只读数据段,有些可以通过立即数(在立即寻址方式指令中给出的数称为立即数;立即寻址方式:操作数紧跟在操作码的后面,与操作码一起放在指令代码中)来实现的常量(如“int i=5”中的“5”)不存放在只读数据段,而是直接编码在指令里,存放在在正文段

3)const修饰的全局变量是存放在常量段的,但是使用const修饰的局部变量不存放在常量段,存放在栈段

4)对于字符串常量,编译器会在常量段中自动去重,让每种字符串常量只有一份

5)为了提高空间的利用率,有些系统中.rodata段是多个进程共享的

6)程序加载运行时,.rodata和.text通常合并到一个段(Text Segment)中,操作系统将这个段只读保护起来,防止意外的改写

1.2代码段(.text)

  ,也叫正文段,存放代码

1.3.数据段

1)存放全局变量静态变量

2)初始化数据段(.data):存放已经初始化的

3)未初始化数据段(.bss):存放未初始化的

4).data和.bss在程序加载时合并到一个段(Data Segment)中,这个段是可读可写的

5)c++不区分初始化的和未初始化的,它们占同一块区域

1.4.堆

  动态内存的分配

1.5.内存映射段

1)常被用来加载共享库(动态库)

2)内存映射:将虚拟内存空间与磁盘上的文件关联起来,这个过程叫内存映射

1.6.栈

  存放局部变量

1.7栈与堆的区别

1)管理方式:对于栈来讲,是由编译器自动管理,无需我们手工控制;对于堆来说,释放工作由程序员控制,容易产生内存泄露

2)空间大小:一般来讲在32位系统下,堆内存可以达到3G的空间(4G有1G要给内核);而栈的最大容量是事先规定好的(例如,在VC6下面,默认的栈空间大小是1M,可修改)

3)碎片问题:对于堆来讲,频繁的new/delete势必会造成内存空间的不连续,从而造成大量的碎片,使程序效率降低;对于栈来讲,则不会存在碎片,因为栈是先进后出的结构,一个内存块要从栈中弹出,在它上面的后进的内存块肯定要先被弹出

4)生长方向:对于堆来讲,生长方向是向上的,也就是向着内存地址增加的方向;对于栈来讲,它的生长方向是向下的,是向着内存地址减小的方向增长;

5)分配方式:堆都是动态分配的;而栈有2种分配方式:静态分配和动态分配,静态分配是编译器完成的,比如局部变量的分配,动态分配由alloca函数(类似于malloc,专门在栈中申请空间的函数)进行分配,但是即使是动态分配,它也和堆是不同,栈的动态分配是由编译器进行释放,无需我们手工释放

6)分配效率:栈是机器系统提供的数据结构,计算机会在底层对栈提供支持:分配专门的寄存器存放栈的地址,压栈出栈都有专门的指令执行,这就决定了栈的效率比较高;堆则是C/C++函数库提供的,它的机制是很复杂,例如:为了分配一块内存,库函数会在堆内存中搜索连续的足够大小的空间,如果没有足够大的空间(可能是由于内存碎片太多),就需要操作系统重新整理内存空间,这样就有机会分到足够大的内存,然后进行返回。显然,堆的效率比栈要低得多

2.内核空间

2.1内核代码段

  存放内核的代码和数据,所有进程的内核代码段都映射到同样的物理内存,并在内存中持续存在

2.2与进程有关的数据结构段

  存放进程都各自的PCB页表,并映射到不同的物理内存

上一篇: 字典树
下一篇: 信号(signal)
o
粉丝 0
博文 500
码字总数 0
作品 0
私信 提问
加载中
请先登录后再评论。
Linux进程地址空间 && 进程内存布局[转]

一 进程空间分布概述 对于一个进程,其空间分布如下图所示: 程序段(Text):程序代码在内存中的映射,存放函数体的二进制代码。 初始化过的数据(Data):在程序运行初已经对变量进行初始化的数据...

osc_qkqoqioc
2018/05/25
23
0
动态链接

动态链接 要解决空间浪费和更新困难这两个问题最简单的办法就是把程序的模块相互分割开来,形成独立的文件,而不再将它们静态地链接在一起。简单地讲,就是不对那些组成程序的目标文件进行链接,...

osc_mersr09e
2018/09/08
2
0
brk() 和 mmap() 内存映射

参考博文:http://www.cnblogs.com/huxiao-tee/p/4660352.html x86平台下linux进程虚拟地址空间分布(2.6.7以前版本)     mmap区域与栈区域相对增长,只有1GB连续的虚拟地址空间可用。 ...

osc_y4jbxqkl
2018/02/08
4
0
深入探究:操作系统为什么要引入虚拟地址?

在进入正题前先来谈谈操作系统内存管理机制的发展历程,了解这些有利于我们更好的理解目前操作系统的内存管理机制。 一 早期的内存分配机制 在早期的计算机中,要运行一个程序,会把这些程序...

登上王者的男人
06/23
0
0
虚拟地址的理解

原文:http://blog.csdn.net/do2jiang/article/details/4690967 在进入正题前先来谈谈操作系统内存管理机制的发展历程,了解这些有利于我们更好的理解目前操作系统的内存管理机制。 一 早期的...

点滴空间
2016/03/14
7
0

没有更多内容

加载失败,请刷新页面

加载更多

如果你失明了,你怎么编程? - How can you program if you're blind?

问题: Sight is one of the senses most programmers take for granted. 视觉是大多数程序员认为理所当然的感官之一。 Most programmers would spend hours looking at a computer monitor......

技术盛宴
27分钟前
12
0
如何删除使用Python的easy_install安装的软件包? - How do I remove packages installed with Python's easy_install?

问题: Python's easy_install makes installing new packages extremely convenient. Python的easy_install使安装新包非常方便。 However, as far as I can tell, it doesn't implement th......

fyin1314
57分钟前
11
0
如何将逗号分隔的字符串转换为数组? - How to convert a comma separated string to an array?

问题: I have a comma separated string that I want to convert into an array, so I can loop through it. 我有一个逗号分隔的字符串,我想将其转换成数组,因此可以循环遍历它。 Is the...

富含淀粉
今天
13
0
深源恒际:担心个人身份被冒用?不存在!

本文作者:c****t 近日,苟晶被冒名顶替身份参加高考的事件在社会各界掀起广泛热议。事件调查结果公布后,舆论风向逆转,吃瓜群众认为当事人夸大其词消费了公众情绪,一边对当事人所遭遇的不...

百度开发者中心
昨天
5
0
CKEditor 5 + SpringBoot实战(三):SpringData JPA数据持久化

在本系列的文章中,我将介绍如何在Spring Boot Application中使用CKEditor编辑器。介绍的内容包括基本环境的搭建,文件上传,SpringData JPA数据持久化,CKEditor5的安装,CKEditor图片上传,...

树下魅狐
今天
9
0

没有更多内容

加载失败,请刷新页面

加载更多

返回顶部
顶部