.net CLR在哪里存储静态类?

.net CLR在哪里存储静态类?,.net,clr,.net,Clr,这里很多人都很困惑 普通类将其数据存储在堆中,对吗?以及指向堆栈的引用(指针) 当堆栈超出范围时,下次垃圾回收器启动并从堆中移除内存时 现在对于静态类,内存不能被垃圾收集器清理,因为整个程序都需要内存。而且一开始就没有办法得到参考资料 所以当我们调用控制台时。比如说写什么?程序从何处获取引用(它在何处存储对静态类的引用?)?或者它只是直接调用它,但是如何调用呢 我认为你把课堂、记忆的位置和记忆的保存方式搞混了。创建普通类的实例时,该实例的内存位于堆上。对该实例的引用可能位于堆上的对象中(如果将对

这里很多人都很困惑

普通类将其数据存储在堆中,对吗?以及指向堆栈的引用(指针)

当堆栈超出范围时,下次垃圾回收器启动并从堆中移除内存时

现在对于静态类,内存不能被垃圾收集器清理,因为整个程序都需要内存。而且一开始就没有办法得到参考资料


所以当我们调用控制台时。比如说写什么?程序从何处获取引用(它在何处存储对静态类的引用?)?或者它只是直接调用它,但是如何调用呢

我认为你把课堂、记忆的位置和记忆的保存方式搞混了。创建普通类的实例时,该实例的内存位于堆上。对该实例的引用可能位于堆上的对象中(如果将对象的不同实例中的成员变量设置为该实例);或者堆栈变量(如果您向方法内的对象声明变量或将其传递给函数调用),或者它可能位于全局根列表中(如果它是静态引用,例如单例引用)

无法实例化静态类。任何地方都没有对类的“引用”(类型信息除外)。它的方法只是CLR加载程序集时加载到内存中的函数。您可以创建一个指向这些方法之一的委托,但也不能将对实例的引用作为类的引用。这只是一个指向函数的指针

例如,请看以下代码:

class ObjectWrapper
{
    Object obj = new Object();
}

static void Main(string[] args)
{
    ObjectWrapper wrapper = new ObjectWrapper();
    ...
}
Main方法创建ObjectWrapper类的实例。此实例位于堆上

在ObjectWrapper实例中,有一个类对象的实例位于堆上。对这个类的引用在实例内部,所以我想您可以将该引用视为“生活在堆中”

现在,将其与以下代码进行比较:

class Singleton
{
    static readonly instance = new Singleton();
}
Singleton对象的实例也存在于堆中。但是,该引用是静态引用。它由CLR在全局或“根”引用列表中维护

现在看看这个静态类:

class ObjectWrapper
{
    Object obj = new Object();
}

static class HelperMethods
{
    static int DoSomethingUseful(ObjectWrapper wrapper1)
    {
        ObjectWraper wrapper2 = wrapper1;
        // code here
    }
}

HelperMethods是一个静态类。不能实例化HelperMethods类。堆上不能有来自此类的任何对象。但是,在doSomethingUser方法中,它有两个对堆栈上ObjectWrapper类实例的引用。一个传入,一个在方法中声明。

为了给您一个简单的答案,静态类“存储”在所谓的装入器堆上。装载机堆是一种特殊的非GC堆,具有非常可预测和严格的增长率。当.NET应用程序启动时,实际上会创建几个AppDomain。除了主应用程序域之外,还有系统和共享应用程序域,它们包含系统名称空间和mscorelib、特殊堆(例如加载程序堆)以及CLR本身

有关详细说明,请阅读以下MSDN杂志文章:


尽管是几年前的,但它仍然适用。(但是,我不能说.NET 4.0是否改变了这么多。)

我不理解这个问题的任何部分。你说的“its value”和“its ref”是什么意思?我想他说的是如何将可执行代码与数据成员分离。除其他问题外,它是“its”。那么,你是在问静态类的引用存储在哪里,从哪里引用?我是在问静态类的引用存储在哪里。就“根”而言,查看这篇文章,它解释了.NET的GC算法,并阐明了根在GC中的作用。这个答案中有几点并不完全准确。首先,“在任何地方都没有对它的“引用”的说法是不正确的。对每个类型(静态或其他)的引用都保存在加载程序堆上。整个类型系统在加载程序堆上进行管理,并引用类型及其成员。另外,“这个类永远不会消耗堆上的内存”也是不正确的……虽然它不消耗GC堆空间,但它确实消耗装载器堆上的堆空间。引用仅仅是指针的想法也是不正确的…CLR使用了许多级别的间接寻址。请参阅我在回答中链接的文章,以完全理解类型系统。它不是简单的C或C++,有一个以上堆,有一个以上的堆,“指针”是不常见的比“引用”,这往往是间接指向几次,才真正获得的“事物”的引用,概念“静态”类不生活在“堆”是谬误。根据其结构,一个静态类可能在几个堆上有自己的部分。