首页 新闻 会员 周边 捐助

对象的内存分配问题

0
悬赏园豆:120 [已解决问题] 解决于 2013-01-08 14:26

    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.如果以上是这样分配的,那就是 等号 左边的变量分配在 堆栈,右边的值分配在托管堆中,是不是这样?

各位解释一下,谢谢!

Qlin的主页 Qlin | 老鸟四级 | 园豆:2403
提问于:2013-01-08 12:35
< >
分享
最佳答案
0

我重写一段代码,接下来我的解释都是基于这段代码的:

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),静态成员总是在堆上。

收获园豆:68
水牛刀刀 | 大侠五级 |园豆:6350 | 2013-01-08 13:45

谢谢,理解了一点。

你的 上面那副图,在 heap中,

1.  u1 和 u1的值是否 是分开的?

2. length1 和 值2 是否是分开的?

3. 他们的 静态变量 左边和右边是否 是分开的两块区?

如下图:

Qlin | 园豆:2403 (老鸟四级) | 2013-01-08 14:00

@Qlin: 回答1和2:我标记个u1只是为了让你知道这个是u1的值,实际在栈上根本不存在“变量名”这个东西的。 回答3:更详细的图

水牛刀刀 | 园豆:6350 (大侠五级) | 2013-01-08 14:09

@水牛刀刀: 

我的疑问基本了解了,非常感谢你的回答!

Qlin | 园豆:2403 (老鸟四级) | 2013-01-08 14:14
其他回答(4)
0

值类型肯定是存放在栈上,引用类型肯定是存放在堆中

static标识只是标识该对象在加载时被创建,其他和普通对象没区别

收获园豆:10
Rich.T | 园豆:3440 (老鸟四级) | 2013-01-08 12:52

这个 引用类型 和值类型的分配 是你这样说的。细点说说吧,

u1 这个变量是分配在 堆栈,但是 u1指向的那个对象值分配在 堆 中吧?

支持(0) 反对(0) Qlin | 园豆:2403 (老鸟四级) | 2013-01-08 13:10

@Qlin: 

1. u1分配:先在堆栈上分配一个变量u1,再在托管堆中分配一内存new User(),再将u1指向new User(); 是不是这样的?

这个理解是对的

支持(0) 反对(0) Rich.T | 园豆:3440 (老鸟四级) | 2013-01-08 13:23

@Rich.T: 

谢谢,兄弟 那说说 static int length2 = 2; 吧, 左边 和右边是怎么分布的?

支持(0) 反对(0) Qlin | 园豆:2403 (老鸟四级) | 2013-01-08 13:34

@Qlin: 

前面说了呀,static标识只是标识该对象在加载时被创建,其他和普通对象没区别

支持(0) 反对(0) Rich.T | 园豆:3440 (老鸟四级) | 2013-01-08 13:35
1

CLR via C# 买本这本书看看

收获园豆:30
chenping2008 | 园豆:9836 (大侠五级) | 2013-01-08 13:01

书上也是 这样带过,有没有 更细的 说说

u1 这个变量是分配在 堆栈,但是 u1指向的那个对象值分配在 堆 中吧?

支持(0) 反对(0) Qlin | 园豆:2403 (老鸟四级) | 2013-01-08 13:11

@Qlin: 这个本 你不得不知道.net 也不错的

支持(0) 反对(0) chenping2008 | 园豆:9836 (大侠五级) | 2013-01-08 13:14

@chenping2008: 

谢谢! 就是 在 看这本书 时  想到的疑问

支持(0) 反对(0) Qlin | 园豆:2403 (老鸟四级) | 2013-01-08 13:20

@Qlin: 其实你只是关注了那些变量,你有没有看到还有一个program的实例的。你说的那些变量都是在program的实例中的

支持(0) 反对(0) chenping2008 | 园豆:9836 (大侠五级) | 2013-01-08 13:22

@chenping2008: 

这个 知道,  u1 这个变量是在 堆栈上, u1指向的 值 在 托管堆上,是不是?

支持(0) 反对(0) Qlin | 园豆:2403 (老鸟四级) | 2013-01-08 13:24

@Qlin: 看看上面一幅图。手画的。可以简单的理解一下。

支持(0) 反对(0) chenping2008 | 园豆:9836 (大侠五级) | 2013-01-08 13:28

@chenping2008: 

大哥 ,你这幅图 我倒是不同意啊

支持(0) 反对(0) Qlin | 园豆:2403 (老鸟四级) | 2013-01-08 13:39

@Qlin: 说说

支持(0) 反对(0) chenping2008 | 园豆:9836 (大侠五级) | 2013-01-08 13:41

@chenping2008: 

呵呵 谢谢,还在理解中...

支持(0) 反对(0) Qlin | 园豆:2403 (老鸟四级) | 2013-01-08 14:07
0

我觉得只要分清楚引用和基本数据类型就可以了,冒昧地问一下,分这么细的原因???

收获园豆:2
angelshelter | 园豆:9914 (大侠五级) | 2013-01-08 13:10

这个 弄清楚了, 很多问题 可以解析

支持(0) 反对(0) Qlin | 园豆:2403 (老鸟四级) | 2013-01-08 13:20
0

参考篇博文:http://www.cnblogs.com/simbadan/archive/2012/10/16/2725854.html

对值类型和引用类型内存分配进行了说明,并且也解说了引用类型内嵌值类型时的内存分配。

 

至于静态成员与非静态成员的内存分配实际上是一致,只是在成员上访问的方式不一致。

收获园豆:10
滴答的雨 | 园豆:3660 (老鸟四级) | 2013-01-08 13:12

谢谢,文章 不错

支持(0) 反对(0) Qlin | 园豆:2403 (老鸟四级) | 2013-01-08 14:11
清除回答草稿
   您需要登录以后才能回答,未注册用户请先注册