c#中的堆和栈的问题

来源:百度知道 编辑:UC知道 时间:2024/06/26 00:03:36
在引用类型中,引用变量存放的地址是存放在栈中,而地址所指向的引用是放在堆中的,这样理解对吗
比如用new创建一个类对象,Person p = new Person();
其中p存放的是地址,放在栈中,new Person()是在堆中创建的
以上理解是否有误呢,等待回答

你的理解准确。

实际上,这个引用变量p是放在当前线程的堆栈上,它占4个字节(32位OS),指向的对象在托管堆上。

另外,为了保证托管堆内存的连续性,保证内存分配的性能,.Net的垃圾收集机制会定期扫描托管堆,把不再有引用变量指向的对象清理掉,并会移动那些仍在使用中的对象(同时修改引用变量p得值,使它指向新地址)——就像我们的磁盘碎片整理那样,这样就保证了托管堆中空余内存的连续性,使得托管堆内存的分配和访问更加快速。

这也就是为什么,在.Net中不能直接用指针指向托管对象的原因——垃圾收集器移动托管对象时,不能同时更新指针值,会导致指针指向错误的地址。

所以,.Net也提供了关键字fixed,去锁定托管对象,告诉垃圾收集器,不要移动被锁定的对象,这时就可以直接使用指针了,当然这是在非安全模式下(unsafe)

基本上可以这样理解.
不过,p是一个对象,不仅仅是一个对象的引用.
不能把p割裂成对象的引用和对象的内存分配两部分来看,这样不合适,c#就是隐藏了对象的引用和对象的内存分配的复杂细节的