虚拟内存

Linux系统的内存管理

虚拟内存

	-----以下都是32位系统为前提-----
	为什么要设置虚拟内存?
	由于物理内存地址往往不够大,一个进程便需要占用到大量的内存,但是我们不可能
只运行一个或几个进程,所以需要创建虚拟地址空间来拓展进程对内存的使用。
	
	由于要遵守这个规则,必须了解虚拟地址空间内部有些什么,如何工作的
	1、因为操作系统要求安全性,它不允许进程在运行时直接访问内核,进程想要访问
操作系统必须通过操作系统做中转。
	2、进程之间互相独立,当需要跨进程通信时,必须调用操作系统创建一个共享的文
件(因为linux操作系统内一切皆文件),通过一方写入、一方读取完成两个进程之间通
信。
	3、我们每个进程在运行的时候有独立的4G字节的虚拟地址空间,进程只能访问虚拟
地址空间,无法直接访问物理地址。4G虚拟地址空间:0~3G:用户空间;3~4G:内核
空间;只有一张独立唯一的init_mm表与内存映射,所有进程共用它
		注意:访问了没有映射过、没有权限的虚拟内存地址会产生段错误(非法访问)

虚拟地址空间是怎么生成的:

		虚拟地址空间是通过操作系统软件、MMU(内存管理单元)中的地址翻译硬件
和一个存放在物理内存中叫`页表`的数据结构工作的。页表就是记录了虚拟页和物
理页映射关系的一种数据结构。每次地址翻译硬件将一个虚拟地址转换为物理地址时
,都需要读取页表。
	[这篇文章详细讲了这些概念](https://blog.csdn.net/csdn_gjx/article/details/73139334)

进程映像

		进程在内存空间中分布的情况叫进程映像。下面是它们在内存中的存储表(从
低地址到高地址):
		1、代码段/制度段:二进制指令、字符串字面值、具有const且被初始化过的全局
	变量静态变量
		2、数据段:没有const属性的被初始化过的全局变量和静态变量
		3、BSS段:没有初始化过的全局变量和静态变量,进程一旦加载成功就会把这段
	内存清理为0
		4、堆区:动态的分配、管理内存,需要程序员操控
		5、栈区:非静态的局部变量:函数的参数、返回值
		6、命令行参数及环境变量表:存储命令行参数、环境变量
		注意:堆内存的使用从低地址想高地址,栈的使用为从高地址向低地址,并且在
	堆和栈之间有一段空隙

#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
// 常属性全局变量
const int const_global = 100;
// 初始化的全局变量
int init_global = 100;
// 末初始化的全局变量
int uninit_global;

int main(int argc,char* argv[],char* environ[])
{
	// 常属性静态局部变量
	const static int const_static = 100;
	// 初始化的静态局部变量
	static int init_static = 100;
	// 末初始化的静态局部变量
	static int uninit_static;
	// 常局部变量
	const int const_local;
	// 局部变量
	int local;
	// 堆地址
	void* heap_ptr = malloc(4);
	// 字符串字面值地址
	const char* const_str = "hehe";

	printf("----------从低到高依次是----------\n");
	printf("代码段:%p\n",main);
	printf("只读段:%p %p %p\n",&const_global,&const_static,const_str);
	printf("数据段:%p %p\n",&init_global,&init_static);
	printf("BSS段:%p %p\n",&uninit_global,&init_static);
	printf("堆:%p\n",heap_ptr);
	printf("栈:%p %p\n",&const_local,&local);
	printf("命令行参数:%p\n",argv[0]);
	printf("环境变量表:%p\n",environ[0]);
	printf("cat /proc/%d/maps\n",getpid());
	getchar();
}

环境变量表

	环境变量表
			main函数的第三个参数char **environ
			extern来获取环境变量environ
	环境变量函数
		int clearenv(void)		清空环境变量表
			成功返回0,失败返回-1
			
		char* getenv(const char* name)		获取环境变量的值
			name:环境变量名称
			成功返回地址,失败返回NULL
			
		int putenv(char* string)		添加环境变量,sring存在则更新,不存在则添加
			string:要添加的环境变量
			成功返回0,失败返回-1
			
		int setenv(const char* name,const char* value,int overwrite);	
		设置name环境变量的值为value
			name:环境变量的名字
			value:要修改的值
			overwrite:不为0则更新,为0则不变
			
		int unsetenv(const char* name)		从环境变量表中删除name
		
		注意:操作系统中的环境变量是一块特殊的存储空间,程序自己添加的环境变
	量需要自己准备存储空间,并且该环境变量只能影响自己,不能影响别人
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值