c# - 如何演示 C# 变量的存储位置,堆栈或堆

标签 c#

我知道 C# 和 Java 一样,将源代码翻译成字节码并由 VM 运行,因为 C# 的情况是 CIL 存储在程序集中并由 CLR 执行。开发人员几乎不需要像 C++ 一样关心变量在堆栈上或堆上(由 GC 处理)的位置,对吗?

他们是否有任何快速直接的方法来证明变量存储在堆栈或堆上?例如,如果我告诉某人引用类型变量存储在堆上或本地值类型变量存储在堆栈上(对吗?)。我怎样才能明确地表明这一点?在 C++ 中,我可以通过 VS 内存窗口获取变量的内存地址并查看其存储在堆栈或堆内存中的值。

最佳答案

Developers scarcely need to care about where the variable is on stack or on heap, right?

没错。为存储选择的技术是运行时的实现细节。

我注意到您省略了寄存器作为存储的可能选择。许多变量已注册,因此它们既不会进入堆栈也不会进入堆。

更好的理解方式是有短期存储长期存储

Is there any quick and straightforward way to demonstrate that a variable is stored on stack or on heap?

尝试计算变量的生命周期。如果您可以轻松做到这一点,并且生命周期小于或等于创建它的方法激活的持续时间,那么它很可能在短期池中。如果不是,它可能在长期池中。

In C++, I can get a variable's memory address and view its value stored in stack or heap memory by VS memory window.

使用 & 运算符可以更改变量的存储位置!如果您获取变量的地址,则它无法注册 因为寄存器没有地址。改变它试图描述的内容的技术是不可靠的技术。

此外,您可能忘记了在 C++ 中堆栈和堆并不是唯一可能的存储位置。

For example, if I tell someone the reference type variables are stored on heap or the local value type variable on stack(right?). How can I show that explicitly?

由于这些陈述是假的,所以您根本无法显示。引用总是在堆上,而值类型的局部变量在堆栈上,这是完全错误的。示例:

void M()
{
    string s = "";
    ...

空字符串 位于长期存储池中,但空字符串最初并未存储在s 中。 对空字符串的引用 存储在s 中。该引用可以放入短期池中。

请记住,引用类型的实际引用根本不在变量中。引用类型的变量包含引用——这就是它们被称为引用类型的原因。

现在,引用类型的字段是一个变量,而那个变量没有已知的生命周期,所以那个变量必须放在长期存储池中:

class C { public int x; }
...
C M() { C c = new C(); return c; }

x 是一个值类型的变量,但是因为它是一个属于引用类型的字段,所以它必须在长期池中。 c 是一个引用类型的变量,所以它持有一个引用;变量 c 的生命周期 很短,因此 c 进入短期池。再次强调,不要将引用与被引用的事物混淆

例子:

Action<int> M()
{
    int x = 123;
    return y => { x = y; Console.WriteLine(x); };
}

局部变量 x 是值类型,但您无法计算它的生命周期,因此它必须在长期存储池中。

既然你说的引用类型变量入堆,值类型局部变量入栈的说法是假的,没法证明它的真实性。

关于c# - 如何演示 C# 变量的存储位置,堆栈或堆,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/25050314/

相关文章:

c# - 如何在类中创建一个调用时会出现 "connect to my Database"的方法?

c# - HashSet UnionWith()方法在C#中的性能问题

c# - 在进行一些密集计算之前等待多个快速属性更改事件 (C#)

c# - 包含大量项目和图像的列表框占用过多内存

c# - 循环范围和内存问题

c# - SL3 透明/玻璃子窗口?

c# - 并行扩展 : Help Me Understand LazyInit<T>

c# - 如何在 C# 中将一种日期格式更改为另一种日期格式,例如 10/10/2014 更改为 2014-10-10(年-月-日)?

c# - 命名空间 'FriendlyUrls' 中不存在类型或命名空间名称 'Microsoft.AspNet'

c# - 如何以编程方式填充现有 PDF 文档