Class 个实例的内存管理

Memory Management for Class Instance

我对 .Net 中的内存管理有疑问。根据我的理解,内存分配和恢复如下:

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

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

  3. 对于栈中分配的内存,内存会在 LIFO 方法,当执行完成时。

我对以下情况有疑问:

Class MathLibrary{

int number1;
int number2;

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

}

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

这里的内存分配是如何发生的,我知道这个对象(数学)的引用将存储在堆栈中,实际内存将在堆中分配。如果那样的话,为值类型(两个整数变量)和方法定义分配的内存在哪里。

For all value types, framework will allocate memory in the stack.

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

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

For all reference types, the memory will be allocated in the heap, which will be later flushed out or managed by the GC.

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

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

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

你对值类型的理解是错误的!一般有这两条黄金法则:

  1. 将在堆上分配引用类型。
  2. 值类型和指针(对其他对象的引用)将在声明的位置分配,而不是总是在堆栈上!

此外,关于StackHeap还有这两个事实:

  1. Stack 负责跟踪代码中正在执行的内容(方法调用、传递参数……)。
  2. Heap负责跟踪对象。

因此在您的示例中,两种值类型(number1 和 number2)都在 class 中声明,这是一个引用类型,因此作为您的 class 实例的对象将被分配到Heap 两种值类型也是如此!由于 maths 对象实际上是对实际对象的引用,因此它完全取决于它的声明位置! 例如,如果它是在方法中声明的,Stack 将负责跟踪调用的内容,因此 maths 引用将驻留在堆栈中并指向 Heap 上的实际对象。但如果它被声明为实例成员,它将位于 Heap.