内存分配:堆栈vs堆?
我对堆栈与堆之间的内存分配基础感到困惑。 按照标准定义(每个人都说的事情),所有的值类型将被分配到堆栈,并且引用类型将被放入堆中 。
现在考虑下面的例子:
class MyClass
{
int myInt = 0;
string myString = "Something";
}
class Program
{
static void Main(string[] args)
{
MyClass m = new MyClass();
}
}
现在,如何在c#中发生内存分配? MyClass
的对象(即m
)是否会被完全分配给堆? 也就是说, int myInt
和string myString
都会去堆?
或者,该对象将被分成两部分,并将分配给这两个内存位置,堆栈和堆?
m
在堆上分配,并且包含myInt
。 原始类型(和结构体)在堆栈上分配的情况是在方法调用期间,它为堆栈中的局部变量分配空间(因为速度更快)。 例如:
class MyClass
{
int myInt = 0;
string myString = "Something";
void Foo(int x, int y) {
int rv = x + y + myInt;
myInt = 2^rv;
}
}
rv
, x
, y
都会在堆栈中。 myInt
是堆中的某个地方(并且必须通过this
指针访问)。
您应该考虑将对象分配为实现细节的问题。 对于存储对象的位的确切位置无关紧要。 可能很重要的一个对象是引用类型还是值类型,但是您不必担心它将存储在何处,直到您开始优化垃圾回收行为。
虽然引用类型总是在当前实现中的堆上分配,但值类型可能会分配到堆栈上 - 但不一定。 值类型仅在堆栈上分配,因为它是未包含的非转义本地或临时变量,该变量未包含在引用类型中,也未分配到寄存器中。
有什么我错过了吗?
当然,如果我没有链接到Eric Lippert关于这个主题的帖子,我将会失职:
“所有VALUE类型将被分配到堆栈”是非常非常错误的; 结构变量可以作为方法变量驻留在堆栈上。 但是,某种类型的字段与该类型相同。 如果某个字段的声明类型是一个类,则这些值作为该对象的一部分存储在堆中。 如果一个字段的声明类型是一个结构体,那么这些结构体就是那个结构体所在的结构体的一部分。
即使方法变量可以放在堆上,如果它们被捕获(lambda / anon-method),或者(例如)迭代器块的一部分。
链接地址: http://www.djcxy.com/p/14533.html