1. 什么是虚拟内存?
因为目前程序都运行在支持多道程序的系统上,让每个程序都直接使用物理地址是相当危
险和不稳定的。很容易引发访存冲突,甚至造成系统崩溃。所以在现代计算机系统中,程
序都使用虚拟内存来取代直接使用物理内存。虚拟内存对于每个进程来说是自己独占的,
通常为4G, 进程可以独立支配这4G虚拟内存。而不用理会当前系统有多少物理内存,别的进程又是如果使用这些物理内存的。虚拟内存到物理内存的映射,以及不同进程访问物理内存的冲突,这些问题都交由操作系统和硬件去完成了。这样就大大简化了开发程序的难度,每个程序只要处理好自己的4G内存就行了。
3, 什么是交换分区,及其作用?
每个进程有自己的4G虚拟内存,通常物理内存都远远小于这些虚拟内存的和。为了节省使用物理内存,操作系统常常使用了延迟加载技术,只有当虚拟内存确实被访问的时候,才分配相应的物理内存供程序使用。另外,操作系统还会把某些暂时用不到的物理内存换出到磁盘上,然后把挪出的物理内存交给最需要的进程。当要重新使用那些被换出的数据的时候,再把它们从磁盘上换入。当然每次换入换出都是以页为单位的。用来保存换出内存数据的磁盘空间,就是交换分区。 Linux上叫Swap分区,Windows上叫虚拟内存(注意与上文提到的程序虚拟内存空间的区别)
0xFFFFFFFF
0xBFFFFFFF
.
. 用户空间(3G)
BSS
代码段
6.栈的大小和栈溢出
栈的大小在不同平台上设定不同,但都有一个上限,当栈的使用超过这个上限的时候,就
会触发tack overflow或者segmentation fault一类的错误。理论上堆和栈都可以占据整个虚存的3G用户空间,但栈的大小必须设置成一个适中的值,如果小了,很容易在分配栈空间的时候(主要是调用某个函数的时候),触发栈溢出。如果栈上限设置得过大,因为属于一个进程的线程共享同一个虚存空间。所以如果每个线程使用的栈过大,则进程能创建的线程就越少。
8.什么是内存泄漏?
在堆的使用过程中,一个很重要的问题就是"内存泄漏"。也就是malloc出来的内存,在不使用之后,用户未能及时调用free释放。因为虚存没有释放,相应的物理内存也没有释放,内存泄漏的堆积最终将耗尽系统所有的内存。为了克服内存泄漏问题,Small Pointer, Garbage Collection等技术被大量的研究和使用。但最有效的办法还是在编写程序的时候时刻留意这个问题,小心处理每一次malloc操作。要注意的是,"内存泄漏"只是运行时问题,当进程结束的时候,操作系统就会收回所有分配给该进程的物理内存。
10.堆、栈对应的物理内存
不论堆和栈在使用管理上有什么不同,但他们都位于虚存空间,使用的是虚拟内存。只有
当真正使用这些分配的虚拟内存的时候,系统才会分配相应的物理内存供其使用。当堆、
栈被释放回收的时候,虚拟内存被标记为未分配,而相应的物理内存会被系统回收。
也就是当我们执行malloc的时候,整个过程应该是这样的:调用malloc()动态分配内存 --> 在malloc维护的内存堆中查找有无可用的大小合适的虚拟内存块 --> 如果没有,则用brk(),mmap()等函数向系统申请新的虚存空间。并返回合适大小的内存块给用户。--> 当真正使用的时候分配的虚存块的时候,系统将其映射到合适的物理内存。
</div>