内存管理初认识

0x01 内存简介

​ 对于每个程序都有其独立的 4 G 的虚拟内存空间。

Windows 在默认的情况下会将高地址的 2GB 空间分配给内核(也可以配置 1GB)。
Linux 默认情况下将高地址的 1GB 空间分配给内核。

​ 其中的 32 位系统程序存放布局图示意如下:

image-20210522133935796

​ 对于其中的进程空间,可以进行如下的划分:

image-20210522134417600

0x02 堆和栈

​ 堆和栈是两个东西,各有不同

栈:

​ 由系统分配与回收内存,从高地址向低地址增长;大小上限对于应用层一般为 1 M 到 10 M ,内核层一般 12 K 到 24 K 不等;由于由系统分配其效率较高;用来记录函数调用过程,也称为栈帧。

栈帧一般包含:函数参数、返回地址,旧 ebp ,函数内局部变量等。

堆:

​ 由程序员分配回收(利用 malloc 和 free 函数),从低地址向高地址增长;大小上限由系统中有效虚拟内存决定;效率较低,且会产生内存碎片;堆在堆头部使用一个字节表示大小,剩余空间存储内容由程序员在程序中的计算决定

0x03 内存地址

​ 地址可以分为三类:逻辑地址、线性地址、物理地址

逻辑地址:由编译器生成,也叫相对地址,即在汇编指令中的地址(操作数),所以有的进程可能有一样的逻辑地址。

线性地址:也称为虚拟地址,在分段中的段偏移地址就是线性地址, 线性地址是由分段机制从逻辑地址转化而来

物理地址:这是 CPU 在存取数据时,最终在地址总线上发出的电平信号,依靠该地址来访问对应数据。若需要得到物理地址,需将逻辑地址经过分段,分页等机制转化而来,这个过程我们称之为寻址。

​ x86 中常用的寻址模型有两种:实模式分段模型、保护模式扁平模型

分段模型:

​ 对于 16 位的系统,寄存器只有 16 位寻址空间位 2 16 2^{16} 216(64 KB),而地址总线有 20 位,寻址空间为 2 20 2^{20} 220(1 MB),为了能成功寻址,将 1 M 的存储空间分为 16 个 64 KB 的逻辑段,于是地址分为两部分:段地址、偏移地址。
​ 段地址即逻辑段在主存中的起始位置,存放在段寄存器中,20 位地址中低四位省略为 0 。
​ 偏移地址即距离段起始位置的偏移量,存放在另一段寄存器中,由于每个段大小不超过 64 KB ,所以也可以由 16 位数据表示。
​ 所以段地址左移 4 位再加上偏移地址即为内存地址。

扁平模型:

​ 在 32 位系统中,寄存器和地址总线都为 32 位,故不需要分段,直接一个基地址就可以了。

实模式:

​ 指运行在 20 位地址总线中,寻址空间 1MB,寄存器 16 位,1 M 空间分成 16 个 64 KB 的段。利用 (CS << 4 ) + IP 寻址

保护模式:

​ 指运行在 32 位地址总线中,地址为虚拟地址,只有通过页表或者段描述符表的映射来获取物理地址。

现在的系统大多都是保护模式扁平模型,是利用页表机制寻址的。

0x04 内存泄漏

​ 当我们在堆上利用动态分配的内存并没就有进行释放,使得系统内存资源出现浪费,这称为内存泄漏,严重的内存泄漏可能会导致系统崩溃的问题。

预防:

​ API 的合格使用;malloc 和 free 的配对使用;尽量做到谁分配谁释放;多方使用时,可以使用引用计数,当计数归零时自动释放

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值