C#类代码是否加载到RAM中?

5
我想知道当您实例化C#类时,实际的代码是否会加载到RAM中?
例如,如果我有两个类CLASS A和CLASS B,其中类A有10000行代码但只有一个字段,即int。而Class B有10行代码,也有一个字段,即int。如果我实例化Class A,它是否会占用比Class B更多的RAM,因为它的代码行数更多?
补充问题是,如果代码行与类一起在内存中加载,它们是否会为每个类的实例都加载?还是只需一次加载所有实例?
提前致谢。
3个回答

9
在桌面框架中,我认为方法是逐个进行即时编译的。我不知道当类第一次加载时,是否会将类的IL完全加载到RAM中,或者它们只是内存映射到程序集文件。
无论哪种方式,对于非泛型类型,您都可以获得所有实例的单个副本。对于泛型类型(和方法),情况会稍微复杂一些 - 对于所有引用类型类型参数,都有一个JIT表示,而对于每个值类型类型参数,则有一个JIT表示。因此,List<string>和List<Stream>共享本机代码,但List<int>和List<Guid>则不共享。(根据需要推断具有多个泛型类型参数的类型。)但对于相同构造类型的所有实例,您仍然只能获得一个副本 - 对象不附带其自己的本机代码副本。

很有趣... CLR 内部书籍是否涵盖了这种东西。我不记得在语言规范中读到过它。 - Andrew Rollings
好的,感谢您的快速回复。因此,如果您正在创建大量单个类的实例,则在减少其代码行数时不会获得任何重要的好处(从内存角度来看)。 - PB_MLT
@Andrew:这当然不是语言规范的一部分,也不应该是。但CLR通过C#涵盖了这一点。@Spi1988:是的,大多数程序将使用更多的内存来存储数据而非代码,以我个人经验而言。 - Jon Skeet

4
类型A的实例所占用的内存与类型B完全相同。类型实例使用的内存量直接取决于它包含的字段,因此如果两种类型都包含相同的字段,则两种类型的实例将包含相同的内存量。当然,如果您有可变长度的字段,例如字符串、数组、集合等,则必须考虑这一点,但如果每种类型的字段设置为相同的值,则将使用相同数量的内存。
在应用程序域中,每种类型的方法指令所包含的代码只会加载一次,而不是针对每个类型实例加载一次。正如Jon所说,重要的是记住每个封闭泛型类型(所有类型参数已声明)都是一个单独的运行时类型。
顺便说一句,重要的不是你的类型包含多少行源代码,而是这些源代码编译成多少IL。然而,如果一个类型有10行源代码,另一个类型有10,000行源代码,那么后者的IL很可能会更大。您可以使用.NET Reflector等工具检查IL。

1

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接