跟我一起学Linux系统编程006C-进程内存分配,堆分配brk、malloc、free

Linux系统编程006C-进程内存分配,堆分配brk、malloc、free

 上上个记录《Linux系统编程006A-进程、内存布局》,上一个记录《Linux系统编程006B-进程内存布局、mmap调用、环境变量》中,主要是讲解了三件事:(1)进程与程序的区别(2)Linux进程内部的内存布局(3)Linux的整体虚拟地址的机制。本文要讲第四件事:进程的内存分配。

1 Linux进程内存布局的要点回顾:

(1)每个进程的虚拟地址空间分布

Linux使用虚拟地址空间,大增了进程的寻址空间,一个进程由低地址到高地址分别为:

  • 1 保留段:从0开始到0x08048000这一段。
  • 2 只读text段:只读空间,包括:代码段、rodata 段(C常量字符串和#define定义的常量)
  • 3 数据(data+BSS)段:保存全局变量、静态变量的空间
  • 4 堆heap:就是平时所说的动态内存, malloc/new 大部分都来源于此。其中堆顶的位置可通过函数 brk 和 sbrk 进行动态调整。
  • 5 mmap内存映射区:如动态库、共享内存等映射物理空间的内存,一般是 mmap 函数所分配的虚拟地址空间。有的也称这个空间为:文件映射区。
  • 6 栈:用于维护函数调用的上下文空间,一般为 8M ,可通过 ulimit –s 查看。
  • 7 内核虚拟空间:用户代码不可见的内存区域,由内核管理(页表就存放在内核虚拟空间)。

(2)Linux 对所有虚拟内存进行管理的几个关键概念

  • 每个进程都有独立的虚拟地址空间,它并不是真正的物理地址;
  • 虚拟地址可通过每个进程上的页表(在每个进程的内核虚拟地址空间)与物理地址进行映射,获得真正物理地址;
  • 如虚拟地址对应物理地址不在物理内存中,则产生缺页中断,真正分配物理地址,同时更新进程的页表;如果此时物理内存已耗尽,则根据内存替换算法淘汰部分页面至物理磁盘中。

(3)32 位系统与64位系统,在进程空间上的差别

32位Linux系统有4G 的地址空间: 其中,用户空间位于0x08048000~0xbfffffff。内核空间位于0xc0000000~0xffffffff之间。内核空间,包括内核代码和数据、与进程相关的数据结构(如页表、内核栈)等。栈顶往低地址方向变化(%esp 执行);堆顶_edata往高地址方向变化(brk/sbrk 函数控制分配)。

64位系统,进程空间当然与32位不太一样。

64位系统拥有 2^64 的地址空间,但地址空间大小不是2^32,而一般是2^48。为啥不需要也不是2^64呢?

2^48 = 256TB,也就说只用48位就达到了256TB空间
2^64 = 256TB * 65536 = 16777216 TB

256TB已经够大的了,当真要用全部的64位来寻址空间。你是设计者也会自觉避免毫无意义的浪费。所以,事实也正是如此,64位Linux使用48位来表示虚拟地址空间,40位表示物理地址。

cat /proc/cpuinfo  
address sizes	: 39 bits physical, 48 bits virtual  

注意:上面是我在ubuntu20上的测试数据。个人总觉得“39 bits physical”,应该是“40 bits physical”,这可能是一个小的语意错误,因为程序对序号或索引值的计算,多数是由0开始!

所以,算下来,
0x0000000000000000~0x00007fffffffffff 表示用户空间, 0xFFFF800000000000~ 0xFFFFFFFFFFFFFFFF 表示内核空间,共提供 256TB(2^48) 的寻址空间。看着这种长长的数字,真是头大!(有人总结了:这两个区间的特点是,第 47 位与 48~63 位相同,若这些位为 0 表示用户空间,否则表示内核空间。这在编程时可能有用。)

64位进程在布局模式上与32位进程没有区别:用户空间地址由低到高,仍然是只读段、数据段、堆、文件映射区域和栈。

2 内存分配方式

有人说,第一,Linunx整体内存访问的机制是虚拟地址,它实现了物理与虚拟地址相互映射。第二,进程内存布局又由编译器和内核给限定了。稍不注意,比如访问进程保留区、进程内核空单,就会引发内存越界错误。

难道进程就没有一丁点的对内存进行管理的权力?

说句实话,进程的确受限太严,但并非是个奴隶,在内存访问方面还是有点自由度的。从操作系统角度来看,不考虑共享内存,进程分配内存有两种方式,分别由两个系统调用完成:brk和mmap

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

虎哥的世界

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值