堆的工作原理和如何为引用数据类型分配内存?(续)

0 views
Skip to first unread message

大伟

unread,
Sep 7, 2006, 3:34:30 AM9/7/06
to csh...@googlegroups.com
Customer实例没有放在堆栈中,而是放在内存的堆中。在这个例子中,现在还不知道一个Customer对象占用多少字节,但为了讨论方便,假定是32B。这32B包含了Customer实例字段,和.NET用于识别和管理其类实例的一些信息。
 
为了在堆上找到一个存储新Customer对象的存储位置,.NET运行环境在堆中搜索,选取第一个未使用的,32B的连续块。为了讨论方便,假定其地址是200000,arabel引用占用堆栈中的799996~799999位置。这表示在实例化arabel对象前,内存的内容应如图7-2所示。
 
给Customer对象分配空间后,内存内容应如图7-3所示。注意,与堆栈不同,堆上的内容是向上分配的,所以自由空间在已用空间的上面。
 
下一行代码声明了一个Customer引用,并实例化一个Customer对象。在这个例子中,需要在堆栈上为mrJones引用分配空间,同时,也需要在堆上为它分配空间:
 
       Customer mrJones = new Nevermore60Customer();
 
该行把堆栈上的4B分配给mrJones引用,它存储在799992~799995位置上,而mrJones实例在堆上从200032开始向上分配空间。
 
从这个例子可以看出,建立引用变量的过程要比建立值变量的过程更复杂,且不能避免性能的降低。实际上,我们对这个过程进行了过分的简化,因为.NET运行库需要保存堆的状态信息,在堆中添加新数据时,这些信息也需要更新。尽管有这些性能损失,但仍有一种机制,在给变量分配内存时,不会受到堆栈的限制。把一个引用变量的值赋于另一个乡同类项的变量,就有两个"引用内存中同一个对象的"变量了。当一个引用变量出作用域时,它会icong堆栈中删除,如上一节所示,但引用对象的数据仍保留在堆中,一直到程序停止,或垃圾收集器删除它为止,而只有在该数据不再被任何变量引用时,才会被删除。
图7-2.jpg
图7-3.jpg
Reply all
Reply to author
Forward
0 new messages