linux 段页式内存管理

http://blog.chinaunix.net/uid-24227137-id-3723898.html

页是信息的物理单位,分页是为了实现离散分配方式,以消减内存的外零头,提高内存的利用率从;或者说,分页是由于系统管理的需要,而不是用户的需求。短是信息的逻辑单位,它含有一组其意义相对完整的信息。分段的目的是为了能更好的满足用户的需求。

进程是如何使用内存的clip_image002

对于任意一个普通的进程都会涉及到5种不同的数据段,

代码段:存放代码

数据段:存放程序静态分配的变量和全局变量

BSS:未初始化的全局变量

堆:用于存放进程运行中被动态分配的内存段,大小不固定。Malloc分配内存时,新分配的内存的添加到堆上(堆扩张),free释放内存时称为堆缩减。

栈:存放局部变量,函数调用时传入的参数和返回的参数都保存在栈中。

如图所示:数据段、bss、堆段通常是被连续存储的,内存位置上是连续的。而代码和栈往往会被独立存放。栈向下生长,堆向上生长。

进程内存空间

Linux中采用虚拟内存管理技术,用户看到和接触到的都是该虚拟地址,无法看到实际的物理内存地址。利用虚拟地址使得用户不能直接访问物理内存,进程间也各自互不干涉,起到保护的作用;另一方面,用户程序可使用比实际物理内存更大的地址空间。4G进程空间分为两个部分,1-3G为用户空间,4G为内核空间,用户通常情况不能访问内核空间,只有用户进程进行系统调用等时刻时可以访问内核空间。

进程内存管理

进程内存管理的对象是进程线性地址空间上的内存镜像,这些内存镜像其实就是进程使用的虚拟内存区域。进程的虚拟空间是个32位或64位的地址空间,空间大小取决于体系结构。如果要查看某个进程占用的内存区域,可以使用linux 下的/proc/maps获得。

注意:你一定会发现进程空间只包含三个内存区域,没有上面提到的堆、bss等,事实上,程序内存段和进程地址空间中的数据段内存区域是种模糊对应,也就是说,堆、bss、数据段(初始化过的)都在进程空间中由数据段内存区域表示。

进程内存的分配和回收?

创建进程fork(),程序载入execve(),映射文件mmap(),动态内存分配malloc()/brk()都需要分配内存给进程。不过这时进程申请和获得的还不是实际内存,而是虚拟内存,准确的说是“内存区域”,进程对内存区域的分配最终都会归结到do_mmap()函数上来。

进程所能直接操作的地址都是虚拟地址,当进程需要内存时,从内存获得的仅仅是虚拟的内存区域,而不是实际的物理地址,进程并没有获得物理内存,获得的仅仅是对一个新的线性地址的使用权。实际的物理内存只有当进程真的去访问新获取的虚拟地址时,才会有“请求页机制”产生缺页异常,该异常是虚拟内存机制赖以生存的基本保证,它会告诉内核去真正为进程分配物理页,并建立对应的页表,根据页表机制虚拟地址才实实在在的映射到了系统的物理内存上。

页面置换算法(LRU):最近最少使用算法

地址映射过程中,若在页面中发现所要访问的页面不在内存中,则产生缺页中断。当发生缺页中断时,os必须选择一个页面将其移出内存,而用来选择淘汰哪一页的规则叫做页面置换算法。LRU算法算法选择过去一段时间里最久未使用的页面。LRU算法存在如何实现的问题,需要实际硬件支持,计数器和栈的实现都会造成多次访问内存的软件开销,实际中使用LRU的近似实现clock算法。

静态链接和动态链接

静态链接和动态链接都是共享代码的方式。

采用动态链接库,lib中的指令都会全部直接包含在最终生成的EXE文件中。但是若使用DLL,DLL不必包含在最终的EXE文件中,动态链接是指在生成可执行文件时不将所有程序用到的函数链接到一个文件,因为有许多函数在操作系统带的dll文件中,当程序运行时直接从操作系统中找。而静态链接库就是把所有用到的函数都全部链接到exe文件中。

posted @ 2016-01-29 14:11  wxquare  阅读(905)  评论(0编辑  收藏  举报