c# - 仅仅声明一个简单类型的变量会分配内存吗?

标签 c# variables declaration

我读了this question在 C 中,我在 C# 中有同样的问题。

代码这样说对吗

int a;

a 在初始化之前保留了四个未分配的字节?或者初始化是第一次分配字节的地方?

最佳答案

没有赋值的 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/

相关文章:

此处不允许声明 JAVA 变量

c - 未使用的可变错误

javascript - 使用先前声明的变量在 fib 序列 javascript 中查找第 n 个值

javascript - 变量在声明之前如何使用?

c++ - 在 C++ 的各种文件中多次包含一个类

c# - 当我的第一页内容较少时,XtreReport 显示第二个空页? Winforms开发工具

c# - Windows 窗体复选框已更改还是已更新?

c# - FluentNhibernate + 私有(private)集

c - 为什么 gcc 提示 gets()

c# - 如何在asp.net 网站中向sql server 中插入数据?