操作系统-进程映像、虚拟内存

随便写写,感觉这方面比较冷门,不会有什么人看

进程映像
程序是保存在磁盘上的可执行文件,加载到内存中被操作系统调用执行的程序叫进程,所以说系统里只有进程没有程序,一个程序可以同时被执行多次形成身份不同的进程
进程在内存空间的分布情况叫进程映像,从低地址到高地址依次排列的是:
代码段/只读段:
二进制指令、字符串字面值、具有const属性且被初始化过的全局、静态变量
数据段:被初始化过的全局变量和静态变量
BSS段:没有初始化过的全局变量和静态变量,进程一旦加载成功就会把这段内存清理为零
栈:动态的分配、管理,需要程序员手动操作,从低地址向高地址扩展
堆:非静态的局部变量,包括函数的参数、返回值,从高地址向低地址使用
和堆内存之间存在一段空隙,一方面是为堆和栈的增长预留空间,另一方面存放空间
命令行参数及环境变量表:命令行参数、环境变量

虚拟内存
每个进程都有各自独立的4g字节的虚拟地址空间,我们在编程时永远都是在虚拟地址空间,永远无法直接访问物理地址(1、为了安全,2、利用映射让程序使用更大的地址空间)

4g分为 0-3g的用户空间,3g-4g的内核空间
用户空间访问内核空间是通过系统调用(以函数形式,但不是函数)进入内核与内核交换数据
如果内存地址没有被映射过或者访问没有权限的内存地址,就会产生段错误(非法的内存访问)
一个进程对应一个用户空间,进程一旦切换,用户空间也会发生变化,但内核空间由操作系统管理,它不会随着进程的切换而变化,内核空间由内核所管理的一张独立且唯一的init_mm表进行内存映射,而用户空间的表时每个进程一张

注意:每个进程的内存空间完全独立,不同的进程间交换虚拟内存地址没有任何意义,所以进程之间不能直接进行通信,需要由内核中转、协调

malloc首次分配内存时至少映射33页,即使通过free释放全部内存,最初的33页也还存在
虚拟内存到物理内存的映射以页为单位(1页=4k=4096字节)

内存管理API
它们都可以进行映射内存的取消映射(系统级的内存管理)
void *sbrk(intptr_t increment);
increment:
0 获取未分配前的内存首地址(也就是已经分配尾地址)
>0 增加内存空间
<0 释放内存空间
返回值:未分配前的内存首地址,以字节为单位

 int brk(void *addr); 
 功能:设置为分配内存的首地址
 返回值:成功返回0,失败返回-1

他们都可以进行映射内存的取消映射(系统级的内存管理),他们背后维护这一个指针,该指针记录的是未分配的内存的首地址(当前堆内存的最后一个字节的下一个位置)
他们都可以进行映射内存的取消映射的功能(系统及的内存管理),但为了方便期间,sbrk一般用于分配内存,brk用于释放内存
注意:sbrk/ brk分配的释放的都是使用权,真正的映射工作由其它系统调用完成(mmap/munmap)

#include<sys/mman.h>
void* mmap(void *addr,size_t length,int prot,int flags,int fd,off_t offset);
功能:把虚拟内存地址与物理内存或文件建立映射关系
addr:要映射的虚拟内存地址,如果为NULL操作系统会自动选择一个虚拟地址与物理内存映射
length:要映射的字节
prot:权限
flags:映射标志
fd:文件描述符(与内存映射没有关系)
offset:文件映射偏移值
返回值:映射成功后的虚拟内存地址,如果出错返回值为0xffffffff

int munmap(void *addr,size_t length);
功能:取消映射
addr:需要取消映射的内存首地址
length:需要映射的字节数
返回值:成功返回0,失败返回-1

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值