什么时候.NET中的静态类加载到内存中?

时间:2017-01-14 01:52:48

标签: c# .net internals

正如标题所示,我感兴趣的是静态类何时被加载到.NET中的内存中,特别是C#。我假设它与Java中的this question和静态方法中的this question类似,因为它是在第一次使用时加载的。另外,一旦它在内存中,它会一直存在,直到应用程序终止或者当垃圾收集器来清理使用它的类时它会被清理干净吗?

我意识到静态类使用的少量内存在具有8 + GB RAM标准的计算机世界中并不是非常重要,但了解内部结构总是很有趣。

编辑:

答案让我想要在这个问题上添加更多内容并通过一个例子来澄清。如果我理解正确,在下面的示例中,Contraption.SomeString将首先放在内存中,紧跟Contraption.AnotherString,第一次循环。

public static class Contraption
{
    public static string SomeString = "Some String";
    public static string AnotherString = "Another String";
}

public class Processor
{
    public void Process(List<SomeClass> items)
    {
        foreach(var item in items)
        {
            if(item.Name == Contraption.SomeString)
            {
                //do something
            }
            if(item.Name == Contraption.AnotherString)
            {
                //do something
            }
        }
    }
}

3 个答案:

答案 0 :(得分:4)

关于静态字段初始化,重要的一点是static constructor的使用。 CLR有一个类加载器组件,它在程序中使用时从内存管理器加载一个类(元数据信息)和内存分配请求。元数据加载是一次性工作,发布它只是根据需要请求内存

正如在讨论中所理解的那样,静态类变量在任何地方的第一次使用时被加载,并被赋予内存,但是使用静态构造函数可以确保在调用类加载器时将它们初始化为第一件事。 ,它是一次性调用,可以对类中的所有静态变量进行初始化,这甚至在第一个使用策略之前,因为当CLR(mscoree.dll)是为给定程序加载组件时。

静态构造函数在任何情况下(程序重启除外)都不会在第一次调用之后被调用,即使有异常,也可以通过将它们设置为null来收集其广泛使用的静态变量

答案 1 :(得分:1)

我假设你指的是静态类中的字段(或非静态类中的静态字段)。它们将在首次使用前初始化。它在C#规范中描述:

  

10.4.5.1静态字段初始化

     

类的静态字段变量初始值设定项对应于按照它们出现在类声明中的文本顺序执行的赋值序列。如果类中存在静态构造函数(第10.11节),则在执行该静态构造函数之前立即执行静态字段初始值设定项。否则,静态字段初始化器在第一次使用该类的静态字段之前的实现相关时间执行。

静态类成员被视为垃圾收集根,并且始终可以访问。

您可以通过将静态成员重置为null或其他对象来强制回收对象:

public static class Foo 
{
    public static object Bar = new object();
}

// somewhere later
Foo.Bar = null;
// the object can be collected now.

答案 2 :(得分:0)

静态变量在AppDomain的生命周期内持续存在,而在.NET中,每个应用程序可以有多个AppDoamins。虽然大多数情况下,每个应用程序只有一个AppDomain,而其他AppDomain主要是为沙盒插件创建的。

https://msdn.microsoft.com/en-us/library/2bh4z9hs(v=vs.110).aspx