类实例的内存管理

时间:2016-03-19 07:25:43

标签: c# .net memory-management clr

我怀疑.Net中的内存管理。根据我的理解,记忆被分配并重新获得如下:

  1. 对于所有值类型,框架将在堆栈中分配内存。

  2. 对于所有引用类型,内存将在堆中分配,     随后将由GC清除或管理。

  3. 对于堆栈中分配的内存,将清除内存 执行完成时的LIFO方法。
  4. 我对以下情况表示怀疑:

    Class MathLibrary{
    
    int number1;
    int number2;
    
    public int computesum(){
        return number1 + number2;
    }
    

    }

    MathLibrary maths = new MathLibrary(); // Class instance
    

    如何在此处进行内存分配,我了解到此对象(数学)的引用将存储在堆栈中,实际内存将在堆中分配。如果那时,将为值类型(两个整数变量)和方法定义分配内存。

2 个答案:

答案 0 :(得分:4)

  

对于所有值类型,框架将在堆栈中分配内存。

这并非总是如此。如果在方法中声明了值类型,它将进入堆栈。如果它是类级变量,它将在堆上,因为拥有它的对象是在堆上分配的。

因此,对于MathLibrary,2个整数也将在堆上,因为它们是该对象的字段。

  

对于所有引用类型,内存将在堆中分配,稍后将由GC刷新或管理。

是的,这是真的。但是,要记住的一件重要事情是对象将在堆上分配,但如果在对象中创建此对象,则对象的引用将在堆栈上。实际的对象将在堆上。例如:

public void Foo()
{
   Foo f = new Foo();
}

参考" f"将在堆栈上,但引用引用的实际对象将在堆上。

答案 1 :(得分:2)

您对价值类型的理解是错误的!通常有这两个黄金法则:

  1. 将在堆上分配引用类型。
  2. 将在声明它们的位置分配值类型和指针(对其他对象的引用),而不是总是在堆栈上!
  3. 此外,还有关于StackHeap的这两个事实:

    1. Stack负责跟踪我们的代码中执行的内容(方法调用,传递参数,......)。
    2. Heap负责跟踪对象。
    3. 因此,在您的示例中,两个值类型(number1和number2)都在一个引用类型的类中声明,因此作为类实例的对象将在Heap上分配,因此价值类型!而且,因为maths对象实际上是对实际对象的引用,所以它完全取决于它的声明位置! 例如,如果它是在方法中声明的,Stack将负责跟踪被调用的内容,因此maths引用将驻留在堆栈上并指向{{上的实际对象1}}。但如果它被声明为实例成员,它将驻留在Heap