Unix系统 - 内存管理

今天内容:UNIX/Linux的内存管理(操作系统的核心功能)1关于进程的内存空间划分2虚拟内存地址空间的机制3内存管理的相关函数结构1关于进程的内存空间划分程序是代码编译链接的产物,是存储在硬盘上的文件,程序是静止的。运行起来的程序就是进程,是内存中运行的程序,也就是把程序加载到了内存中,是运行的。CPU(中央处理器)不能直接访问硬盘,但能直接访问内存。程序必须加载到内存中(...
摘要由CSDN通过智能技术生成

一、关于进程的内存空间划分

程序是代码编译链接的产物,是存储在硬盘上的文件,程序是静止的。
运行起来的程序就是进程,是内存中运行的程序,也就是把程序加载到了内存中,是运行的。
CPU(中央处理器)不能直接访问硬盘,但能直接访问内存。程序必须加载到内存中(变成了进程)才能真正运行起来。
但有些时候会把进程也叫程序,主要是为了沟通方便。
一个程序可以有多个进程。

进程的内存空间划分为以下几个部分:
1代码区-用于存放代码(函数)的区域,特点是只读区。函数指针就是指向代码区的地址
2全局区-用于存放全局变量(定义函数外的变量)和static的局部变量
3BSS段-用于存放未初始化的全局变量的区域。
4栈区(堆栈区stack)-用于存放局部变量的区域,包括:函数的参数和非static的局部变量。系统自动管理栈区内存。
5堆区(heap)- 也叫自由区,程序员唯一可以控制的区域。通常内存分 配、回收都是在堆区malloc()、free()都是在堆区。堆区的内存内存,系统完全不管,程序员全权管理堆区内存。
6只读常量区-存放字符串字面值(即""括起来的字符串)和const修饰的全局变量。这个区域也是只读区,很多书都是把只读常量区并入代码区。
只读常量区的一个例子:

char* s1 = "abc";
s1[0] = '1';//这是不可以的,因为"abc"是字符串字面值

编程示例:

include <stdio.h>
include <stdlib.h>

int i1 = 10;//全局
int i2;//BSS
static int i3 = 10;//全局
const int i4 = 10;//只读
void fa(int i5){
   //fa在代码区,i5在栈区
	int i6;//栈
	const int i7 = 10;//栈
	static int i8 = 10;//全局
	int* pi = malloc(4);//堆区
	char* s1 = "acb";//指向只读常量区。也就是s1一直指向"abc",不可修改
	char s2[] = "abc";//指向栈,s2对应着一片存储区而不是只读区,
					//存储区里面是数组类型的变量是可以修改的。
					//char* s1 = "acb"、char* s2 = "acb";s1和1s2一个地址,这是因
					                                 //为只读区里只会存一个"abc"
					//char s1[] = "acb"、char s2[] = "acb";s1和1s2不一个地址
	
	
	printf("i5=%p,i6=%p,i7=%p,i8=%p,s1=%p,s2=%p\n,pi=%p\n",&i5,&i6,&i7,&i8,s1,s2,pi);
	free(pi);
} 
int main() {
   
	printf("i1=%p,i2=%p,i3=%p,i4=%p\n",&i1,&i2,&i3,&i4);
	return 0;
	fa(1);
	printf("fa=%p\n",fa);//函数名就是函数指针
}

二、虚拟内存地址空间的机制

UNIX/LInux使用虚拟内存地址的方式管理内存,比如:
int a = 10;
printf("%p\n",&a);//得到的那个地址就是虚拟地址。每个进程先天都有0 - 4G-1的虚拟内存地址空间,本质上就是整数(编号)。虚拟内存地址本身不能存储任何的数据,必须映射到物理内存或硬盘上的文件后才能存储数据,否则引发段错误。
对虚拟地址空间举个例子,你买房买了2单元402房,房子还没建好,等真正房子建好了才能住进去。
这里补充一下,为啥是4G-1的空间:
32位系统最多能有多少个内存地址?4G个
2的10次方 -> 1024 -> 1k
2的20次方 -> 10241024 -> 1M
2的30次方 -> 1024
1024*1024 -> 1G
2的32次方 -> 4G
关于虚拟地址空间和实际物理内存的关系,如下图:

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值