我发现不一定class对象的reference就一定放在堆栈上,而对象本身放在堆上,因为如果ClassA这样定义:
class ClassA {private ClassB abc = new ClassB();}
在main(){ClassA ab1 = new ClassA();}时,ab1对象放在堆上,ab1内,abc对象的reference也应该在堆上吧。那么什么时候才能肯定一个变量是放在堆栈(stack)而不是堆(heap)上呢?我编了个小例子:
class Class1
{
[STAThread]
static void Main(string[] args)
{
testClassB abc = new testClassB();
abc.doTest();
}
} public class testClass
{
public testClass():this(1){}
public testClass(int a):this(){}
} public class testClassB
{
public void doTest()
{
testClass ak1 = new testClass();
}
}程序很快就报StackOverflowException,testClass的构造器有问题,我想既然testClass是在堆上运行,那至少要把堆的内存(所有内存?)用完再报错吧。

解决方案 »

  1.   

    刚才单步调试了你的程序,楼主是不是想让执行逻辑在public testClass():this(1){}和public testClass(int a):this(){}这两个函数之间反复循环来看看会报什么溢出啊? 我觉得这样达不到你的目的,函数执行是要保护现场——把操作数和指令指针压栈,然后执行完在恢复现场,你这样执行一个死循环的函数调用等于不停的压栈而不弹出,肯定会堆栈溢出,并不能说明abc是分配在托管堆还是线程堆栈,你这样就像是无穷递归,一定会StackOverflowException的。在下表达能力有限,不知道说清楚没有~~~~另外,引用类型都是在托管堆上分配内存;值类型都是在线程堆栈上吧。
      

  2.   

    感谢rib06(诸刃突袭·水面上的小草) 另外你说的:值类型都是在线程堆栈上。如果一个类的成员变量是值类型,如
    public class Test
    {
      public int aa = 23;
      public StructType ab;
    }
    当在另一个类里实例化Test时,那aa和ab应该都在堆上吧。
      

  3.   

    没错,是在堆上。这部分建议你可以参考《.net框架程序设计》,讲的很好的,还有图,一目了然。