读书人

编译器初始化全局变量并分配虚拟内存

发布时间: 2013-10-14 12:54:46 作者: rapoo

编译器初始化全局变量,并分配虚拟内存
本帖最后由 loverszhaokai 于 2013-10-12 19:52:29 编辑 全局变量arr占用100MB空间,arr存放在静态存储区,当程序运行的时候,占用的内存竟然只有几百KB,难道arr没有占用内存?

#include <unistd.h>

char arr[100 *1024 *1024]={'a'};//显示初始化

int main(int argc,char*argv[])

{

while(1)

{

sleep(1);

}

return0;

}


程序开始运行只有几百KB的内存,当我调用memset之后
memset(arr,1,100*1024*1024); //给arr数组全赋值为1

进程占用的内存马上飙到100多MB,为什么开始的时候是几百KB?
我认为是进程没有把虚拟内存映射到物理内存上的原因,只有访问该虚拟内存时,操作系统才会把它映射到物理内存中。为此做了几个实验,不知道结论是否正确。求教。

实验结果在我的博客上。想看的请到这里看。
[解决办法]
从你的实验来看,当你没有使用arr时,编译器会直接把它优化掉。

引用:
全局变量arr占用100MB空间,arr存放在静态存储区,当程序运行的时候,占用的内存竟然只有几百KB,难道arr没有占用内存?

#include <unistd.h>

char arr[100 *1024 *1024]={'a'};//显示初始化

int main(int argc,char*argv[])

{

while(1)

{

sleep(1);

}

return0;

}


程序开始运行只有几百KB的内存,当我调用memset之后
memset(arr,1,100*1024*1024); //给arr数组全赋值为1

进程占用的内存马上飙到100多MB,为什么开始的时候是几百KB?
我认为是进程没有把虚拟内存映射到物理内存上的原因,只有访问该虚拟内存时,操作系统才会把它映射到物理内存中。为此做了几个实验,不知道结论是否正确。求教。

实验结果在我的博客上。想看的请到这里看。

[解决办法]
我用gdb和top做了一下简单的测试,发现:
1、程序刚启动时,系统未给arr分配内存;
2、执行memset时,系统分配相应的内存给arr;
3、但是继续执行时,系统似乎收回了arr的内存。

引用:
编译器分配的内存空间是虚拟的内存地址,我原以为程序开始就会把进程的静态存储区映射到物理内存,从实验结果看,进程访问静态存储区的空间时,操作系统才会把这一部分虚拟内存映射到物理内存。

我想知道,我的结论是否正确。(上面就是我的结论)


Quote: 引用:

从你的实验来看,当你没有使用arr时,编译器会直接把它优化掉。

Quote: 引用:

全局变量arr占用100MB空间,arr存放在静态存储区,当程序运行的时候,占用的内存竟然只有几百KB,难道arr没有占用内存?

#include <unistd.h>

char arr[100 *1024 *1024]={'a'};//显示初始化

int main(int argc,char*argv[])

{

while(1)

{

sleep(1);

}

return0;

}


程序开始运行只有几百KB的内存,当我调用memset之后
memset(arr,1,100*1024*1024); //给arr数组全赋值为1

进程占用的内存马上飙到100多MB,为什么开始的时候是几百KB?
我认为是进程没有把虚拟内存映射到物理内存上的原因,只有访问该虚拟内存时,操作系统才会把它映射到物理内存中。为此做了几个实验,不知道结论是否正确。求教。

实验结果在我的博客上。想看的请到这里看。

[解决办法]
引用:
编译器分配的内存空间是虚拟的内存地址,我原以为程序开始就会把进程的静态存储区映射到物理内存,从实验结果看,进程访问静态存储区的空间时,操作系统才会把这一部分虚拟内存映射到物理内存。

我想知道,我的结论是否正确。(上面就是我的结论)


Quote: 引用:

从你的实验来看,当你没有使用arr时,编译器会直接把它优化掉。

Quote: 引用:

全局变量arr占用100MB空间,arr存放在静态存储区,当程序运行的时候,占用的内存竟然只有几百KB,难道arr没有占用内存?

#include <unistd.h>

char arr[100 *1024 *1024]={'a'};//显示初始化

int main(int argc,char*argv[])

{

while(1)

{

sleep(1);

}

return0;

}


程序开始运行只有几百KB的内存,当我调用memset之后
memset(arr,1,100*1024*1024); //给arr数组全赋值为1

进程占用的内存马上飙到100多MB,为什么开始的时候是几百KB?
我认为是进程没有把虚拟内存映射到物理内存上的原因,只有访问该虚拟内存时,操作系统才会把它映射到物理内存中。为此做了几个实验,不知道结论是否正确。求教。


实验结果在我的博客上。想看的请到这里看。



你的结论基本正确,只是并非“映射”,而是交换。windows刚刚建立进程时,只给予进程一定数量的物理内存(称为驻留集),进程代码留在内存映射文件中,进程运行过程中可能会访问超出驻留集所代表的进程地址空间
的位置,此时就需要从内存映射文件或者虚拟内存中进行交换,驻留集可能会增大,也可能不会,得视驻留集管理算法而定。

还有,你现在见到的只是windows的行为,不同操作系统进程调度的方法不一样,你见到的现象也可能会不一样。
[解决办法]
引用:
Quote: 引用:

Quote: 引用:

编译器分配的内存空间是虚拟的内存地址,我原以为程序开始就会把进程的静态存储区映射到物理内存,从实验结果看,进程访问静态存储区的空间时,操作系统才会把这一部分虚拟内存映射到物理内存。

我想知道,我的结论是否正确。(上面就是我的结论)


Quote: 引用:

从你的实验来看,当你没有使用arr时,编译器会直接把它优化掉。

Quote: 引用:

全局变量arr占用100MB空间,arr存放在静态存储区,当程序运行的时候,占用的内存竟然只有几百KB,难道arr没有占用内存?

#include <unistd.h>

char arr[100 *1024 *1024]={'a'};//显示初始化

int main(int argc,char*argv[])

{

while(1)

{

sleep(1);

}

return0;

}


程序开始运行只有几百KB的内存,当我调用memset之后
memset(arr,1,100*1024*1024); //给arr数组全赋值为1

进程占用的内存马上飙到100多MB,为什么开始的时候是几百KB?
我认为是进程没有把虚拟内存映射到物理内存上的原因,只有访问该虚拟内存时,操作系统才会把它映射到物理内存中。为此做了几个实验,不知道结论是否正确。求教。

实验结果在我的博客上。想看的请到这里看。


你的结论基本正确,只是并非“映射”,而是交换。windows刚刚建立进程时,只给予进程一定数量的物理内存(称为驻留集),进程代码留在内存映射文件中,进程运行过程中可能会访问超出驻留集所代表的进程地址空间
的位置,此时就需要从内存映射文件或者虚拟内存中进行交换,驻留集可能会增大,也可能不会,得视驻留集管理算法而定。

还有,你现在见到的只是windows的行为,不同操作系统进程调度的方法不一样,你见到的现象也可能会不一样。


谢谢,更理解了一些计算机,我看这里http://learn.akae.cn/media/ch20s05.html,认为是虚拟内存与物理内存的映射的。


你理解错里面的内容了,虽然我对链接中的内容并非完全赞同,但文中关于虚拟内存与物理内存之间的关系的阐述是基于交换的,就是那个换页操作。你大概将虚拟地址空间与线性(进程)地址空间、物理地址空间之间的映射关系误解成虚拟内存与物理内存之间的关系了。
[解决办法]
我认为楼主的结论是正确的 但是也是通过页交换实现的!而不是像内存映射文件一样虚拟内存直接对应物理内存
[解决办法]
虚拟内存,是一种假象,是操作系统和CPU联合演的障眼法。
实际是利用有现的物理内存,

和几乎无限的磁盘空间,
进行的页面配置和换页操作。
操作系统掌握一些物理内存用于页面的交换,还有一些页面就存放和分配在磁盘空间。

当执行读写数据指令时,如果数据不在内存----CPU通过分页机构,查询页目录和页表,可以知道页面在不在内存---就产生缺页中断打断读写指令的执行,操作系统的缺页中断代码,就会进行页面调度,把需要读写的页面
调入或者换入
----物理内存页面,已经用完或者接近,
只有把预计,不会很快使用的页面,
和正要使用的页面,做个内存和磁盘之间的调换,一个从内存交换到磁盘上,腾出内存;
另一个交换到内存中,刚刚腾出的页面处,
并更新也表记录---
物理内存页面,只是物理内存的一个位置,页表中记录的是,页面占用的虚拟内存空间,物理内存的位置CPU,
可以通过分页机构计算得到,操作系统则会有位置的记录,以便管理页面。

换页或者调页操作,完成后,CPU继续执行读写指令,就像这个中断不存在一样。
这就是虚拟内存的实现方式。

虚拟内存,只是个表象,
物理内存,磁盘空间,分页机构,页面调度,页表页目录,缺页中断,等
才是虚拟内存存在的实质。

操作系统的,段表页表,虚拟内存分配和空间划分策略,才是虚拟内存,可以开多大的根据。
理论上的虚拟内存空间,是可以很大的。即便32Bits,也应该超过4G。





读书人网 >C++

热点推荐