• 全部
  • C#综合技术
  • C#互联网桌面应用
  • AppLauncher
  • WinForm&WPF
  • C#开发新技术
  • 问答

值类型和引用类型在内存中的位置有什么区别?

comecsdn 2002-09-09 10:58:35
MS说值是存在于堆栈中,引用类型存在于堆中。
一个例子就是
int i;
class j
{
int x
}
j obj;
obj = new j;
i是存在于堆栈中,而obj是一个引用类型存在于堆中
那么<obj所引用的实例中的变量x是存在于哪里的呢?>
是作为预定义类型存在于堆栈中,还是作为引用类型
存在于堆中?

如果在堆栈中,那么基本上所有的类最开始大多数都
是由这些预定义的类型构成,如果在堆中,那么在c#里
所有的预定义类型的变量都是类的一部分,把什么放到
堆栈里?

谢谢

...全文
307 点赞 收藏 4
写回复
4 条回复
切换为时间正序
当前发帖距今超过3年,不再开放新的回复
发表回复
TheAres 2002-09-10
光敲字了,发稿晚了.
回复
TheAres 2002-09-10
我来简单的探讨一下: 我说原理,最后你自己考虑考虑你的问题.
首先,你的例子有一个语法看起来不太舒服,
j obj;obj = new j;
改为j obj;obj = new j(),我们的csc会更高兴些.

首先,win32的管理内存空间是4GB,这4GB的空间称虚拟地址空间,简称虚拟内存,无论堆(heap)还是栈(stack),都在这里面.而我们的计算机一般没有这么大的内存,也不大可能用这么多的内存. 所以给他们做了一下划分,有一部分性能高的化出来,叫栈(stack),令一块叫堆(heap),性能低,但是能装的东西多.

说说值类型是如何放在栈(stack)的.
int i; double d; 计算机会在栈顶开辟4个存储单元,放i(不如是100-103,当然,绝对不是100,仅仅比如,后面都这样),然后有拿了8个来放d;

说说引用行的如何放在堆(heap)中的.
比如
class Class MyClass
{
int i;
double d;
}
MyClass myObj = new MyClass()
首先,windows要计算这个对象要占用的长度,比如,一个int 4 个字节,一个double要8个字节,还有一个要放这个对象多长,(一般是以32字节为最小分配单位),然后分配了一个32个字节的连续字节,比如是以1000开头.来放这个对象的内容. 虽然内容放好了,但是别人并不知道他在那儿,于是就要到栈(stack)上去,开4个字节(比如从160开始),来放这个100(堆(heap)的开始地址).以后有人使用myObj时候,先找160,然后找1000,就找到里面的内容了.

由于的堆(heap)还是栈(stack)原理和速度不同,所以才有了不同的存储方式.比如栈(stack)后来的先走,要想回收前面声明的变量,必须要先回收后面声明的. 要是所有的东西都放在栈里,恐怕不一会就占满了栈的空间. 而堆(heap)就没有这个限制,随时可以回收不用的东西,大不了你的堆(heap)的开始地址先放在栈中.


回复
qqchen79 2002-09-10
Good Question!
>> MS说值是存在于堆栈中,引用类型存在于堆中。
MS好像没有这么说吧?这是绝大多数中文书/文章的common misunderstanding。

引用类型永远都是在堆中分配的,这个没错。不过值类型对象并不是总再栈上分配的,更确切的说,值类型对象总是“就地”分配。比如一个函数的临时变量,如果是ValueType,就会直接在stack上分配;而ref type则是在Heap分配内存,然后把引用放到stack上。而对于类的成员,ValueType总是“就地”在包含对象当中分配内存,比如你的例子,x是在对象obj的内存中占了一块地方;而如果是ref type,则是在Heap中重新分配,obj中保留的指是一个引用。
回复
yarshray 2002-09-09
<obj所引用的实例中的变量x是存在于哪里的呢?>
在受管制的堆中!!!!
回复
发帖
C#
创建于2007-09-28

10.5w+

社区成员

.NET技术 C#
申请成为版主
帖子事件
创建了帖子
2002-09-09 10:58
社区公告

让您成为最强悍的C#开发者