堆 栈 虚拟内存 物理内存的关系

一,背景

自己发现做开发这么年,竟然不是很清楚,然后查了一下资料,根据自己理解总结了一下

二,概述

windows上面物理内存通过页管理【方便物理内存管理,后面堆也是内存管理的算法,只是他依赖虚拟内存】,每一页大小是4K【跟系统有关】

栈是连续内存块,每个线程都一个固定大小栈【1M】,所以我们在函数里面不要数组设置很多,不然就会栈溢出了。c/c++ 可以在vs里面进行设置,其他应该也可以。地址连续为提高内存的访问速度,他的内存管理也非常简单,我们OD或者其他调试工具的时候就会看这个东西,这个无法程序直接体现,除非你自己写汇编语言。栈溢出常常用来远程溢出,以前的strcpy等等函数都没有检测原始数据大小,按照0为结束符号,导致覆盖原来调用压入的运行地址,从而跳转指定的恶意代码,现在基本都换高级语言,很少应用有这个bug。

堆对应程序员语言的new或者malloc(C语言),windows它本质调用HeapAlloc,delete调用FreeHeap,你进入汇编就能看的到。堆内存我认为只是虚拟内存管理小内存的一种算法,他内部分配内存应该也只是虚拟内存(网上是说这么说的),我自己测试时候你分配3000字节的内存,他分配的实际的内存是4K,走的还是虚拟内存分页管理逻辑,从我们开发角度来说,代码基本都是分层,上一层依赖下一层,如果直接操作物理内存,那么怎么标记这块内存已经使用了。

虚拟内存是页管理中对象,我们访问虚拟地址,从而系统要我们访问实际物理内存。我们无法实际操作物理内存,我们操作别的进程内存,可以通过虚拟内存函数进行操作。

下面是window任务管理对应的关系,我们查内存泄漏最好看提交大小,而不是专用内存,因为专有内存可能放的磁盘上面去,那么实际用的物理偏小,但你的程序new的对象确实比物理多很多,程序内存泄漏应该看虚拟内存,而不是实际内存。