最佳答案
没有赋值的 int 声明(如评论中所述)将被编译器优化掉——它根本不会出现在程序中。
假设您在一个函数中(与类型定义相反)并分配 int,分配将在函数开始时从堆栈空间进行(也就是说,int 是从已经专用于该线程的内存中分配的,并且不会导致操作系统分配)。
另一方面,如果 int 是类型定义的一部分(并被使用),那么它将增加该类型的每个实例的分配空间,无论该类型最终被分配到哪里(类的堆,堆或根据用途堆栈结构)。
在任何情况下,它都不会导致 int 本身的指针或引用。
一些进一步的解释:
原始问题通过示例引用了一个 int。 int 是固定长度(4 字节)的数据结构,因此编译器注意到包含相关声明的方法需要 4 个字节来存储它。编译器不会在堆上(放置引用类型的地方)分配这 4 个字节并产生垃圾回收开销,而是在为当前线程的方法局部变量(调用堆栈)保留的内存区域中保留 4 个字节。该内存是在线程启动时从操作系统分配的,并且只为该线程保留。如果线程用完该空间,则称为堆栈溢出。
这里值得注意的是,.NET 确实有 2 个编译器——将 C# 代码转换为 IL 的 C# 编译器,以及在运行时将 IL 转换为机器指令的 JIT 编译器。在我的回答中,当我说“编译器”时,我是在挥手说明我指的是哪个编译器,但结果是一样的。
根据评论,如果我这样做...
void Foo() {
{
int a = 5;
Console.WriteLine(a);
}
{
int a = 7;
Console.WriteLine(a);
}
}
... 那么编译器可能会为第二个变量 a
重新使用分配给第一个变量的堆栈空间,因为它们在语义上是不同的。但这是一种优化。
还值得注意的是,调用堆栈包括方法局部变量之外的其他信息 - 它包括方法的参数、返回值的空间(如果函数返回引用类型,则为指针)以及返回地址好吧。
最后,我要补充一点,在 C# 中,您的方法可能会被 JIT 编译器内联 - 这意味着被调用方法的代码可能会被整体复制到调用方的主体中,以避免方法调用的开销。在这种情况下,堆栈帧也将包含用于被调用方法的局部变量的空间。
关于c# - 仅仅声明一个简单类型的变量会分配内存吗?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/32295985/