class Program { User u1 = new User(); static User u2 = new User(); int lenght1 = 2; static int length2 = 2; static void Main(string[] args) { } }
对 对象的内存分配还是有一些疑问,先不管它的先后顺序。
1. u1分配:先在堆栈上分配一个变量u1,再在托管堆中分配一内存new User(),再将u1指向new User(); 是不是这样的?
2. u2的分配和u1的一样吗,也是u2在堆栈,new User()在托管堆吗?static 变量会被分配到加载堆中Loader Heap,是 指等号右边的分配到加载堆中还是 连左边的一起分配到加载堆中。
3.引用对象Class中的 值类型也是分配在托管堆中,是指 值分配在托管堆中吗?
如 length1, 是值2 分配在托管堆中,length1这个变量是分配在 堆栈吗?
4.如果以上是这样分配的,那就是 等号 左边的变量分配在 堆栈,右边的值分配在托管堆中,是不是这样?
各位解释一下,谢谢!
我重写一段代码,接下来我的解释都是基于这段代码的:
class Program { User u1 = new User(); static User u2 = new User(); int length1 = 2; static int length2 = 2; static void Main(string[] args) { User u3 = new User();
Program p = new Program(); } void M() { int length3 = 3; } }
首先最好不要把u1,u2,length1,length2叫做“变量”(或者xx变量),他们都是Program的成员(member),更准确的说是字段(field),其中u1和length1是实例成员(实例字段),而u2和length2是静态成员(静态字段)。u3和length3是方法里定义的变量。下面回答你的问题:
1. 不对。u1是Program的实例成员,只有创建Program实例的时候才会创建u1。假设你的Main方法中有这么一句:Program p = new Program(); 那么这句执行后,变量p位于Main方法的栈上,它指向堆上的一个Program对象。u1作为成员也是在堆上的。
2. 不对。u2是静态成员,它是在Program类第一次被使用到时随着它的类型Type信息初始化的,同样是在堆上。
3. 见图:
4. 不是。如果你按照我之前的建议去区分“变量”和“成员”的话,那么可以这么说:(方法体内定义的)变量分配在栈上,实例成员分配的哪里取决于它的容器(即它所属的class/struct),静态成员总是在堆上。
谢谢,理解了一点。
你的 上面那副图,在 heap中,
1. u1 和 u1的值是否 是分开的?
2. length1 和 值2 是否是分开的?
3. 他们的 静态变量 左边和右边是否 是分开的两块区?
如下图:
@Qlin: 回答1和2:我标记个u1只是为了让你知道这个是u1的值,实际在栈上根本不存在“变量名”这个东西的。 回答3:更详细的图
@水牛刀刀:
我的疑问基本了解了,非常感谢你的回答!
值类型肯定是存放在栈上,引用类型肯定是存放在堆中
static标识只是标识该对象在加载时被创建,其他和普通对象没区别
这个 引用类型 和值类型的分配 是你这样说的。细点说说吧,
u1 这个变量是分配在 堆栈,但是 u1指向的那个对象值分配在 堆 中吧?
@Qlin:
1. u1分配:先在堆栈上分配一个变量u1,再在托管堆中分配一内存new User(),再将u1指向new User(); 是不是这样的?
这个理解是对的
@Rich.T:
谢谢,兄弟 那说说 static int length2 = 2; 吧, 左边 和右边是怎么分布的?
@Qlin:
前面说了呀,static标识只是标识该对象在加载时被创建,其他和普通对象没区别
CLR via C# 买本这本书看看
书上也是 这样带过,有没有 更细的 说说
u1 这个变量是分配在 堆栈,但是 u1指向的那个对象值分配在 堆 中吧?
@Qlin: 这个本 你不得不知道的.net 也不错的
@chenping2008:
谢谢! 就是 在 看这本书 时 想到的疑问
@Qlin: 其实你只是关注了那些变量,你有没有看到还有一个program的实例的。你说的那些变量都是在program的实例中的
@chenping2008:
这个 知道, u1 这个变量是在 堆栈上, u1指向的 值 在 托管堆上,是不是?
@Qlin: 看看上面一幅图。手画的。可以简单的理解一下。
@chenping2008:
大哥 ,你这幅图 我倒是不同意啊
@Qlin: 说说
@chenping2008:
呵呵 谢谢,还在理解中...
我觉得只要分清楚引用和基本数据类型就可以了,冒昧地问一下,分这么细的原因???
这个 弄清楚了, 很多问题 可以解析
参考篇博文:http://www.cnblogs.com/simbadan/archive/2012/10/16/2725854.html
对值类型和引用类型内存分配进行了说明,并且也解说了引用类型内嵌值类型时的内存分配。
至于静态成员与非静态成员的内存分配实际上是一致,只是在成员上访问的方式不一致。
谢谢,文章 不错