首页 诗词 字典 板报 句子 名言 友答 励志 学校 网站地图
当前位置: 首页 > 教程频道 > 开发语言 > 编程 >

Linux系统编程学习札记(七)内存管理

2012-07-24 
Linux系统编程学习笔记(七)内存管理内存管理:对于一个进程来说,内存是最基本的也是最重要的资源之一。内存

Linux系统编程学习笔记(七)内存管理
内存管理:
对于一个进程来说,内存是最基本的也是最重要的资源之一。内存管理包括:内存分配、内存操作和内存释放。
1、进程地址空间:
Linux将物理内存虚拟化,内核为每一个进程维护一个特殊的虚拟地址空间。这个地址是线性的,从0开始,
到某个最大值。
1)页和页面调度
虚拟地址空间由很多页组成。系统的体系结构和机型决定了页的大小,典型的页大小包括4kb(32位系统)
和8k(64位系统)。每个页面都只有无效和有效两种状态:一个有效的页面和一个物理页或者一个二级存储
介质相关联(一个交换分区或者一个一盘文件),一个无效页没有关联,代表没有分配或者使用。地址空间
无须是连续的,虽然是线性编址,但是中间也有很多未编址的小区域。
2)共享和复制
虚存中的多个页面,甚至是属于不同进程的虚拟地址空间,也有可能被映射到同一个物理页面。这样允许不同
的虚拟地址空间共享物理内存的数据。
另一种情况是MMU会截取这次写操作并产生一个异常;作为回应,内核会透明的创造一份这个页的拷贝以供该
进程进行写操作,这种方式被称为写时拷贝。
3)内存区域
每一个进程都有以下区域:
1)文本区域:包含了程序的代码,字符串,常量和一些只读数据。在Linux中,文本段被标示为只读,并且直接
从目标文件映射到内存。
2)栈段(stack segment)包括了一个进程的执行栈,随着栈的深度动态的增长和收缩。包括程序的局部变量和函数的返回值。
3)数据段,又叫堆,包含了一个进程动态存储空间。它的大小可以变化,是有malloc动态申请,free动态释放的。
4)bss段(bss segment)包含了没有被初始化的全局变量。这些变量根据不同的c标准都有相应的初始值。
Linux从两个方面优化:首先,这个段是用来存放没有初始化的数据,所以连接器实际并不会将特殊的值存储在对象文件,
这样可以减少二进制代码文件的大小。其次,当这个段被加载到内存时,内存只需要简单的根据写时复制的原则将它们
映射到一个全是0的页上,这样非常高效的设置了初始值。
5)很多地址空间包含多个映像文件,比如可执行文件的本身、c和其他的链接库,还有数据文件。可以查看/proc/self/maps
或者pmap的输出查看进程的映像文件。
2、动态申请内存:
内存可以通过自动变量或者静态变量获得,但是所有的内存管理系统的基础都是动态内存的分配、使用和最终的释放。
动态内存是在进程运行时才分配的,而不是在编译时就分配好了,分配的大小也只有在分配时才确定。
1)C中最经典的为获得动态内存的接口是malloc:

#include <string.h>void *memmem(const void *haystack, size_t haystacklen, const void *needle, size_t needlelen);

这个函数名字比较烂,它在指向长度为haystacklen的内存块haystack中查找,并返回第一块和长为needlelen
匹配的子块指针。如果找不到,返回NULL,这个同样是GNU的扩展函数。

热点排行