1、每个进程都有各自互独立的4G字节虚拟内存空间。
2、用户程序中使用的都是虚拟地址空间中的地址,永远无法直接访问实际物理内存地址。
3、虚拟内存到物理内存的映射由操作系统动态维护。
4、虚拟内存一方面保护了操作系统的安全,
另一方面允许允许应用程序使用比实际物理内存更大的地址空间。
5、4G进程地址空间分成两部分:
[0,3G)为用户空间,如某栈变量的地址0xbfc7fba0=3217554336,约3G;
[3G,4G)为内核空间。
6、用户空间中的代码,不能直接访问内核空间中的代码和数据,
但可以通过系统调用进入内核态,
间接地与系统内核交互。
7、对内存的越权访问,或试图访问没有映射到物理内存的虚拟内存,将导致段错误。
如:野指针,指向一块没有进行物理内存映射的虚拟地址。或者越权访问。
8、用户空间对应进程,进程一切换,用户空间随之变化。
内核空间由操作系统内核管理,不会随进程切换而改变。
内核空间由内核根据独立且唯一的页表init_mm.pgd进行内存映射,
而用户空间的页表则每个进程一份。
* 得出结论:两个同时运行的进程同样的一个(虚拟内存)地址
所标识的物理内存是不同的两个。(操作系统内核保证)
9、每个进程的内存空间完全独立。
不同的进程之间交换虚拟内存地址是毫无意义的。
10、标准库内部通过一个双向链表,
管理在堆中动态分配的内存。
malloc(存在<stdlib.h>中)函数分配内存时会附加若干(通常是12个)字节,存放
控制信息。
该信息一旦被意外损坏,可能在后续的操作中引发异常。
2.5、虚拟内存
11、虚拟内存到物理内存的映射以页(4k=4096字节)为单位。
通过malloc函数首次分配内存,至少映射33页。
几时通过free函数释放掉全部内存,
最初的33页仍然保留。
#include <unistd.h>
int getpagesize (void) //返回内存页的字节数,一般是4k
2.5、虚拟内存
写好代码并运行后查看/proc/getpid()/maps文件,查看内存使用情况,
堆空间返回返回十六进制21000这么大地址,除于4096,刚好等于33。
free之后内存并没有真的释放,只是打个标记。基本的33页,并不会直接解除映射。
33页以外可能会解除映射。
但分配一个字节的空间只能用一个字节的空间是安全的。
后面跟上控制信息。往控制信息里面写可能在后续的操作中引发异常。
往33页以内的地方写可能会不稳定,覆盖其它有效数据。
33页以外的其它地方写就会发生段错误。
关闭缓冲区 setbuff(stdout, NULL);
2.5、虚拟内存
2.5、虚拟内存
2.5、虚拟内存
2.5、虚拟内存
网友评论