【问题标题】:Memory allocation for a class that has deep inheritance in .NET.NET 中具有深度继承的类的内存分配
【发布时间】:2011-01-23 20:50:41
【问题描述】:

如果我有 A, B, C, D, E 类和 X, Y, Z 之类的接口,并为这样的系统建模:

class B : A, X
class C : B, Y
class D : C, Z
class E : D

如果A 是一个抽象基类并且E 是感兴趣的类,那么当我创建E 的一个实例时,它是否会在E 之外又创建A, B, C, D, X, Y, Z 的实例?

如果是这样,这会产生巨大的性能开销吗?不是内存,而是运行时和 GC。

【问题讨论】:

    标签: c# .net performance memory-management


    【解决方案1】:

    是的,它会创建 A、B、C 和 D 的“嵌入式”实例
    不,它不会创建 X、Y 和 Z 的实例(因为它们是接口)

    内存分配或 GC(ABCD)没有额外的开销,因为 E 的实例被分配为 1 个块。任何运行时开销都将完全取决于所涉及的构造函数。

    总会有一个构造函数链(从 E 到 A)在执行,可能是默认构造函数,但也可以在 1 级调用多个构造函数。

    【讨论】:

    • 抱歉,没有继承创建的实例!
    • @Obalix,注意嵌入的引号。但是,是的,最终只涉及 1 个实例。
    • 感谢 Henk,所以在这种情况下,例如,如果您要将这些类合并为一个没有继承的类,它们在内存、GC 和运行时性能方面是否几乎相同?
    【解决方案2】:

    继承扩展了 Type 并且不创建实例。您有一个 E 实例,其中包含由 A、B、C、D 和 E 定义的数据。它提供由这些类以及接口 X、Y 和 Z 定义的方法和属性访问器。

    【讨论】:

      【解决方案3】:

      它将创建一个对象 - E 的一个实例 - 但这将包括类层次结构中声明的所有字段。 (接口不能声明字段,因此它们与对象本身的数据无关。)只有字段(以及影响布局的任何属性,诚然)才会对对象占用的内存做出贡献。

      对 E 实例的引用可以“转换”为 A、B、C、D、X、Y 或 Z 类型的引用,作为保持身份的引用转换 - 即它仍然是对同一个对象。

      【讨论】:

      • 谢谢乔恩。当您将 E 转换为上述任何一种时,它会创建一个新实例吗?我认为它适用于基类,对吧?但是对于接口呢?
      • 另外,例如,如果您要将这些类合并为一个没有继承的类,它们在内存、GC 和运行时性能方面是否几乎相同?
      • @Joan:你不转换E的实例,只是对实例的引用'转换',这很便宜。
      • 谢谢 Henk,它是如何工作的?你的意思是引用指针被转换为另一种类型?实际上我认为所有的引用指针都是一样的,即没有关于它所指向的信息。
      • @Joan:在编译时它有很多关于它所指向的信息,即使在非托管语言中也是如此。 .NET 将其扩展到运行时,CLR 验证正确的转换。但是没有物理转换。
      猜你喜欢
      • 2011-01-18
      • 1970-01-01
      • 2019-11-11
      • 2010-12-26
      • 2018-06-15
      • 1970-01-01
      • 2018-04-14
      • 1970-01-01
      相关资源
      最近更新 更多