是从内存中比不使用继承的类更大的另一个类继承的类继承的类

本文关键字:继承 另一个 内存 | 更新日期: 2023-09-27 18:31:42

想象一下我有两个类,class1和class2。

Class1 继承自 baseClass,如下所示:

baseClass
{
private Int64 one;
protected Int64 two;
public Int64 three;
}

类 1 看起来像这样

Class1 : baseClass
{
private Int64 four;
protected Int64 five;
public Int64 six;
}

类 2 看起来像这样:

Class2
{
private Int64 one;
protected Int64 two;
public Int64 three;
private Int64 four;
protected Int64 five;
public Int64 six;
}

如果我要为每个类创建 10k 的数组,哪个会更大?class1 数组会更大,因为 class1 也会包含某种与 baseClass 有关的元数据吗?否则,它们的属性是相同的,因此从技术上讲它们应该是相同的。

是从内存中比不使用继承的类更大的另一个类继承的类继承的类

给定两个引用类型的数组,即:

Class1[] a1 = new Class1[10000];
Class2[] a2 = new Class2[10000];

数组的大小将完全相同。数组的元素只是引用,并且引用始终具有相同的大小,无论它引用的对象如何。参考在 32 位运行时为 4 个字节,在 64 位运行时中为 8 个字节。

至于类实例,我希望它们的大小也相同。类实例本身仅保存类的数据,以及少量其他数据,其中包括对该类类型的引用。类实例本身并不"知道"它是一个派生类。该信息由类型保存。

因此,Class1的类型信息可能略大于Class2的类型信息,但这两个类的实例将占用相同的内存量。

综上所述,使用继承自baseClassClass1将比使用Class2花费几个字节,因为你有两个类的类型信息。但它实际上只是多了几个字节 - 无论类元数据的开销是多少。对于每个类实例,它不会花费任何额外费用。

请注意,这仅提供了相对于彼此的大小的概述。据我所知,没有直接的方法可以知道运行时大小。

baseClass bc = new baseClass();

Class1 class1 = new Class1();
Class2 class2 = new Class2();
long bcSize = 0;
long class1Size = 0;
long class2Size = 0;
using (Stream s = new MemoryStream())
{
    BinaryFormatter formatter = new BinaryFormatter();
    formatter.Serialize(s, bc);
    bcSize = s.Length; //223
}
using (Stream s = new MemoryStream())
{
    BinaryFormatter formatter = new BinaryFormatter();
    formatter.Serialize(s, class1);
    class1Size = s.Length; //298
}
using (Stream s = new MemoryStream())
{
    BinaryFormatter formatter = new BinaryFormatter();
    formatter.Serialize(s, class2);
    class2Size = s.Length; //264
}

除非你使用虚拟方法,否则大小将是相同的。

使用虚拟方法时,该类中的虚拟表指针将产生字节开销。