程序占用的内存分析

转载地址:http://blog.youkuaiyun.com/luansxx/article/details/7702030

操作系统的虚拟内存分配表


OP显示的占用内存是进程的虚拟内存,我们需要了解的是程序实际占用内存的量,也就是物理内存占用。

虚拟内存的地址和实际物理内存的地址之间有对应关系,这个关系是操作系统维护的,CPU负责根据这个对应关系进行地址转换。这种对应关系标准的说法叫“内存映射”。

内存映射以页面映射形式实现。页面是固定大小的地址空间(即虚拟范围),虚拟内存的一个页面映射到物理内存的一个页面。没有必要假设连续的虚拟页面映射到连续的物理页面,即使物理页面不连续,只要虚拟页面连续,必要内存的一段地地址拟地己的虚拟地址空间(即虚拟地址范围),因为程序看到的就是连续的数据,这中间就是地址转换在起作用。

内存映射是一种复杂的关系,有下面的情形。

1.         虚拟页面没有映射物理页面

2.         虚拟页面映射某个物理页面

3.         多个虚拟页面映射同一个物理页面

当然不可能一个虚拟页面映射到多个物理页面。

虚拟内存是进程自身的,每个进程有自己的虚拟地址空间(即虚拟地址范围),虚拟地址空间独立,也就是每个进程都是独立的4G地址空间,但是实际物理内存很难有这么多(特别是嵌入式平台),所以虚拟地址空间可以看成是肯定足够的。

因为虚拟地址空间很大,所以宁可浪费虚拟地址空间也要节约物理内存。对于一个进程来说,虚拟内存使用量与物理内存使用量的差别源于上面的第1、3种映射情形。第2种情形两者是一对一映射,所以数量上一样。

我们再看看第1、3种映射情形的实际应用。

对于第1种情形,虚拟页面没有映射物理页面,一般发生在下列场合:

1.         程序的部分代码,因为某些条件未满足,目前还没有执行。

操作系统采用延迟加载策略,没有访问到的虚拟地址默认没有映射到物理内存,是无效的;但是一旦被执行,就会分配一个物理页面,从程序文件中加载数据(代码也是二进制数据)到该物理页面,并修改映射关系,使虚拟地址生效。另外如果某些代码比较长时间没有被执行(操作系统记录页面的空闲时间),操作系统会解除映射,释放物理内存,因为内存上的数据以后还可以再加载。

2.         程序的静态数据,因为某些条件未满足,还没有被访问到

程序的静态数据也是在程序文件中的,包括全局变量、字符串和编译器产生的静态表。与上面的原理一样,操作系统采用延迟加载策略和回收策略(只针对没有修改过的内存,除非有交换分区,这时可以保存在交换分区中)。

3.         堆中的空洞

程序的堆是程序动态申请释放内存所用的内存池。堆可以向上增长,也会退回。但是必须靠后的内存都释放了,而且堆的大小超过一定量(很多系统是128K)才退回。如果程序释放了前面或者中间的内存,那是不会退回的,这就形成了空洞。空洞映射物的理内存实际上是已经释放了,所以空洞没有映射物理内存。

4.         栈顶保留地址空间

程序的栈是函数一层层调用形式的,函数一层层调用的返回地址记录在栈中,函数调用的参数、函数内部的局部变量都存放在栈中。随着函数返回,局部变量、参数等都被释放,栈占用的内存又回退回来。由于难以估计函数调用层次最大会有多深,所以栈会多保留一些虚拟地址空间,这些虚拟地址空间也采用延迟映射的策略和回收策略(退回的数据肯定没有用了)。

5.         栈顶保护地址空间

如果程序有行为异常,对栈的使用超过了配置量,应该尽快发现,方法是在栈顶端后面额外加上小块(一般一个页面)虚拟地址空间,该地址没有任何权限(不能读写),一旦读写这块内存,操作系统会直接给进程发信号杀死进程。

对于第2种情形,多个虚拟页面映射同一个物理页面,一般发生在下列场合:

1.         多个进程共用同一份代码

这种情形一般发生的使用共享库的时候,还有就是同一个程序启动了多次。因为代码可以共用,所以同一份代码在物理内存中只会有一份,多个进程的虚拟地址都映射到同一个物理地址上。

2.         多个进程共用同一份数据

与上面的情形相同,但必须是只读的数据(其实代码就是只读数据)。

3.         进程内部通过不同权限映射同一段物理内存

这种情形很容易被忽略。物理内存按页面大小分配,如果数据量不是页面大小的整数倍,那么剩余零头对物理内存就形成了浪费。如果两种访问属性的数据(比如代码有读、执行情形,只读数据只有读权限),他们的大小相当于页面大小都有一部分零头,那么可以把这两个零头拼在一起放在一个物理页面上,然后通过两个虚拟页面映射,就能够到达节约内存的同时,仍能进行权限控制力的目的。

综上,程序实际占用物理内存的计算方法应该是:

程序占用内存  =  映射物理内存的加权和

加权值  =  本程序对该物理内存的映射次数  /  该物理内存在整个系统中被映射的次数

简单的讲,要从虚拟内存量中第1、3种映射情形多算的占用量。第1种情形要全部减去,第3种情形要整个系统做一下平均,取平均值。

0
0

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值