首页 > 解决方案 > 静态值类型字段如何访问和修改?

问题描述

我注意到值类型的静态字段没有装箱就存储在堆上。

例如/非静态值类型字段,我知道它们被视为堆上对象(包含字段)的一部分,以便在相关方法调用期间将该对象的引用复制到堆栈帧。

但是由于静态值类型字段不与类的具体实例相关联,请问堆上的静态值类型字段是如何在栈帧中访问和修改的?

举个简单的例子:

class TrialsOnB
{
    public static int _b = 0;

    public int AccessB()
    {
        return _b;
    }

    public void ModifyB(int x)
    {
        _b = x;
    }
}

从重复链接下接受的答案中,我目前的理解是,在 C# 和 Java 中,所有(种类)静态字段都存储在Type类的对象中。因此,如果堆栈帧曾经存在并且其中的数据曾经引用静态字段,它可能会复制Type对象的引用并进行操作。

如果我的理解不正确,有人可以纠正我吗?非常感谢

标签: c#.netmemorycallstack

解决方案


是的,它可以改变。但是,使静态变量独一无二的是静态变量属于类而不是特定对象。

我们可以为一个类创建尽可能多的对象。这些对象将有自己的副本实例变量。但是对于所有对象的静态变量,只有一份静态变量可用。如果一个对象改变了静态变量的值,它也会反映在其他对象中。

我们也可以在不为该类创建对象的情况下访问静态变量。静态变量是加载类时首先加载到内存中的变量。

当第一次引用类型时,静态变量存储在托管堆上,而不是堆栈上。编译类的 Type Object 包含对该对象的引用。

类的 Type Object 将一直保留在内存中,直到它所在的 AppDomain 被卸载。由于堆上的对象总是被编译的类型对象引用,堆上的静态对象永远不会被 GC'ed 并且总是消耗内存直到 AppDomain 被卸载

请看这个


推荐阅读