[英]How does the CLR know if a static field has already been initialized?
关于static fields
/ constructors
我一直想知道一件事。
static class
在第一次引用其字段中的一个时初始化,这很容易。
但是CLR如何知道这是第一次?
CLR维护一个表,其中包含已加载的所有类型及其初始化状态。 如果A
使用的是B
的静态字段,则CLR知道A
使用A
是B
并且在初始化A
时还将初始化B
因此,不对每个访问都执行是否初始化依赖项的检查。 通过类型的依赖图来确保。
如果您对实现细节感兴趣,可以查看DomainLocalModule
中DomainLocalModule的IsClassInitialized
方法及其在创建类实例时的用法 。
我希望这回答了你的问题。
static class
在第一次引用其字段中的一个时初始化,这很容易。
不,不是那么简单。 忽略方法调用,如果static
类未标记为beforefieldinit
,则必须在首次访问其static
字段之前对其进行初始化。 如果将其标记为beforefieldinit
,则可以在此之前进行初始化。 (Jon Skeet 的文章中包含有关beforefieldinit
更多信息 。)
什么时候检查类初始化有什么影响? 由于CLR使用JIT编译,因此它在JIT编译方法时检查类的初始化。 如果该类在beforefieldinit
标记,并且尚未初始化,则JIT编译器会立即对其进行初始化。 然后,它实际上会编译该方法,在此可以假定该类已被初始化,因此无需进行检查。
如果没有beforefieldinit
,那么如果尚未初始化该类,则JIT编译器必须在每次可能的第一个字段访问之前发出检查初始化的代码。 但是,如果该类已经初始化,并且正在对另一个方法进行JIT编译,则JIT编译器不再需要在那里发出检查。
在某些情况下,这可能会对性能产生负面影响。 从上面可以明显看出,要防止这种情况,您需要确保将有问题的类标记为beforefieldinit
。 从C#做到这一点的方法是没有static
构造函数,仅使用static
字段初始化程序。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.