关于win98和win2000的内存堆回收问题,核心编程已经说得很清楚了,但是关于栈的回收方法虽然提及但似乎没有说清楚在此有如下疑问:
98会尽可能快的收回不被使用的堆中的内存块,而2000重视速度所以它往往较长时间占用物理存储器,只有在一段时间后页面不再使用时,才将它返回给页文件,所以堆内存的回收原理比较明白了。不过栈的内存又是怎么回收的呢?
是在一个有局部变量的函数返回时,就立即回收栈内的这些局部变量的内存?还是依然遵循2000的堆回收规则呢
98会尽可能快的收回不被使用的堆中的内存块,而2000重视速度所以它往往较长时间占用物理存储器,只有在一段时间后页面不再使用时,才将它返回给页文件,所以堆内存的回收原理比较明白了。不过栈的内存又是怎么回收的呢?
是在一个有局部变量的函数返回时,就立即回收栈内的这些局部变量的内存?还是依然遵循2000的堆回收规则呢
解决方案 »
- 驱动程序.sys的驱动文件就是一般的可执行文件么?
- 第十二章:程序员的恐惧感
- 如何再次打开被关闭的继承自CControlBar类对象的窗口?如何判断该窗口是否打开的状态?
- 中英文对齐
- 学习MFC看什么书?
- 关于接口与数组
- 我做了个基于对话框的应用程序,我想在这个对话框上加上菜单,应该怎么加?谢谢!还有我用button按下去后,想打开一个对话框来选择文件名
- 这个怪现象你们见过吗???
- VISIO主要用途是干什么的?是作软件分析的吗?
- 如何得到html中的文本内容
- 别了VC++ 我的大老婆
- 怎样做到在对一个文件写的同时要截去前面写的部分?要不断对这个文件写,同时要除掉前面写过的一部分,比如文件写了5次,写第6次之后,去掉第一次写的部分。
{
CBird bird; // bird 变量入栈,调用构造函数 { // <---- 代码块视口
CCat cat; // cat 变量入栈,调用构造函数
cat.EatFish();
} // <----- 视口结束,这里会放置 cat.~CCat() 调用代码,cat生命期结束,出栈 bird.Fly();
return;
} // <----- 函数结束,这里会生成 bird.~CBird() 调用代码,bird生命期结束,出栈
你需要理解影响栈的使用的操作通常是:局部变量的定义,函数调用的参数传递和eip寄存器入栈/出栈
栈的回收是在线程结束时由系统完成的
也就是说,线程的生命周期决定了栈的生命周期
当进程销毁后,这块虚存被释放,残留的对象才被清理干净
当本次函数调用结束后,局部变量先出栈,然后是参数,最后栈顶指针指向最开始存的地址,也就是主函数中的下一条指令,程序由该点继续运行。我想,应该有一定的手段来跟踪这个过程,可以上网找一下。
这篇文章应该对你有用。http://www.cppblog.com/oosky/archive/2006/01/21/2958.html
-------------------------------------------
局部变量对应到栈里的数据空间,没有回收的概念void f()
{
int x = 0;
int y = 0;
int z = 0;
}这行代码,编译器会为他生成
sub ebp, n ;n是指为局部空间保留的空间大小
mov [ebp+n1],0 ;x=0
mov [ebp+n2],0 ;y=0
mov [ebp+n3],0 ;z=0
是用这种方式为局部变量分配空间的,即编译器知道保留多少空间,哪个地址是哪个局部变量用的
需要注意的是,在当前线程中,栈只有一个,局部变量的空间是在这个栈中
f函数退出时
add ebp, n ;这就相当于把空间还给栈了
我这里省略了进入f函数push ebp和保存esp原始寄存器值的部分和退出f函数恢复相应寄存器的部分
{
int x = 0;
f();
}对于函数调用,在进入a的时候,编译器生成的代码为a中的局部变量x分配空间,只是改变ebp寄存器的位置(使其指向栈空间的某个地址),假设x的地址是 0xFFFC
当执行到函数f时,会有 push ebp, sub ebp,n 这样的代码使 f中的变量使用 0xFFF0 - 0xFFFB 这段地址的内存
f 执行完以后 0xFFF0-0xFFFB 就不属于 f 函数中的局部变量了,但是这段内存地址的空间并不会回收带参数的函数会稍复杂一些,不过也只是将参数所需要的数据 push 到栈中(会改变esp的值,在被调用函数中仍然以 ebp+偏移 的方式来访问)栈是一个连续的线性地址空间,它的使用是至顶向下的,函数调用层次的加深就是栈使用空间的偏移从上到下递减的过程