读你必须知道的.net有感--对象之生(1)
《对象和人,俩个世界,一样情怀》--对象之生:
--堆栈的内存分配机制 2008年9月1日
首先请: .NET面向对象世界中的主角--<对象>--闪亮登场;
要想深刻的理解面向对象思想--莫过与那实际实际生活来类比对象世界//在我学习的进程中是深有体会:对象就像个体的人,生而如世,
死而离世。
对象之生:哇!~~~伴随着一声啼哭,一个鲜活的生命来到世上,鼻子是鼻子,嘴巴是嘴巴,而母亲的怀胎十月是人在母体内的成长过程,
母亲为胎儿提供了所有的养分和舒适的环境,这个过程是一次实实在在的生物化构造。对象亦是如此1.在内存中分配一定的存储空间;2.初始
化其附加成员;3.在调用构造函数执行初始化;
作为对象:它的类型分为---值类型、引用类型;
首先让我了解下基础知识:内存分配在哪里?///
CLR 管理内存的区域,主要有三块:
1. 线程的堆栈,用与分配值类型实例。堆栈主要由操作系统管理,而不受垃圾收集器控制,当值类型实例所在方法结束时,其存储单位自
动释放。栈的执行效率高,但存储容量有限。
2. GC 堆,用于分配小对象实例。如果引用类型对象的实例大小小于85000字节,实例将被分配在GC堆上,当有内存分配或者回收时,垃圾
收集器可能会对GC堆压缩。
3. LOH (Large Object Heap) 堆,用于分配大对象实例。如果引用类型对象的实例大小不小于85000字节时,该实例将被分配到LOH堆上,
而LOH堆不会被压缩,而且只在完全GC回收时被回收。
首先堆栈的内存分配机制:
值类型实例总是分配在它声明的地方,声明为局部变量时其被分配在堆栈上,声明为引用类型成员时被分配在托管堆上。
对于分配在堆栈上的局部变量来说,操作系统维护着一个堆栈指针来指向下一个自由空间的地址。当方法调用时都会在栈中创建一个活动记
录(包含参数,返回地址和局部变量),并分配相应的内存空间,这种分配一次性完成。方法执行结束返回时,内存一次性解除。而数据的压栈
出栈是有顺序的,栈内是(FILO)形式。首先入栈的是返回地址;然后是参数,一般以由右往左的顺序入栈;最后是局部变量,依次入栈。方法
执行之后,出栈的顺序正好相反,首先是局部变量,在是参数,最后是那个地址指针。请看以下实例:
using System;
using System.Collections.Generic;
using System.Text;
namespace _._
{
class ValueType
{
public void MyCall()
{
int x = 100;
char c = 'A';
Console.WriteLine("值类型的内存分配机制实例:");
}
}
class MyTest
{
public static void Main()
{
ValueType valuType = new ValueType();
valuType.MyCall();
Console.ReadLine();
}
}
}
看图解密:
当程序执行至MyCall方法时,假设此时线程栈的初始位置为50000,因此堆栈的指针开始指向50000地址空间。方法调用时,首先入栈的是返
回地址,就是方法执行后下一条可执行语句的地址,用与方法返回之后程序继续执行。如图:
然后是整型局部变量x,它将在栈上分配4Byte的内存空间,因此堆栈指针继续向下移动4个字节,并将值保存在相应的地址空间,同时堆栈/
指针指向下一个自由空间。如图:
接着是字符型变量c,在堆栈上分配2Byte的内存空间,因此堆栈指针向下移动2个字节,值‘A’会保存在新的栈上空间。内存分配如图:
最后,MyCall方法开始执行,直到方法体执行结束,执行结果被返回,栈上的存储单元也被自行释放。其释放过程与分配过程刚好相反。
最终的内存分配如图:程序又将回到栈上最初的方法调用地址,继续向下执行。
在此仅为大家奉献上:简单的分配情况...读书去了;待续、、、、~.~


浙公网安备 33010602011771号