属性或get/set方法对对象大小的影响

Kla*_*Nji 6 c# clr memory-management

就对象大小而言,如果公开的属性不表示状态,而只是将其getter和setter调用委托给另一个实体,那么属性如何取代Get/Set方法会影响对象大小?

例如,请考虑以下类:

public class Person
{
   Address _address = new Address();

   public string AddressName
   {
      get{ return _address.Name; }
      set { _address.Name = value; }
   }

   public string GetAddressName(){ return _address.Name; }
   public void SetAddressName(string name){ _address.Name = name; }

}

public Address
{
    public string Name { get; set; }
}
Run Code Online (Sandbox Code Playgroud)

我猜测当创建一个新的Person时,CLR将在确定要分配多少内存时考虑AddressName属性的潜在大小.但是,如果我暴露的只是Get/Set AddressName方法,则不会分配额外的内存来满足AddressName属性.因此,为了节省内存占用,在这种情况下使用Get/Set方法会更好.但是,这将不会对Address类的Name属性产生影响,因为正在保留状态.这个假设是否正确?

Jon*_*eet 15

单个对象的大小不受属性,方法,事件等数量的影响.它会影响类型元数据的大小和JITted代码 - 但不会影响每个对象的大小.这只受实例字段的影响.

我猜测当创建一个新的Person时,CLR将在确定要分配多少内存时考虑AddressName属性的潜在大小.

不,它只关注你的领域.你有一个字段(_address),所以加上正常的对象开销是单个实例所需的所有内存.


Dan*_*ker 5

正如Jon已经回答的那样,对象实例的大小由其实例字段决定.但是,让我详细介绍一下.

对象实例至少与其字段大小的总和一样大.根据字段对齐约束和CLR(公共语言运行时)布局字段的方式,可能需要考虑一些填充字节.对于引用类型,实例有两个额外的隐藏字段:同步块索引和类型引用.两者都是原生整数.在堆上,实例的最小大小为12个字节(无论它们实际需要多少空间).

以下面的课程为例:

class X
{
    byte value1;
    string value2;
    int value3;
    long value4;
}
Run Code Online (Sandbox Code Playgroud)

在32位系统上,一个实例X可能需要28个字节:

  • 同步块索引和类型引用的2倍4字节,
  • 一个字节byte,
  • 三个填充字节,用于对齐下一个字段,
  • 对象引用的四个字节string,
  • 另外四个字节 int
  • 和八个字节long,

如您所见,getter和setter,方法和构造函数不占用每个对象实例中的空间.相反,有一个单独的对象(您知道Type)维护一个方法列表(getter,setter和构造函数也是方法)并包含该类型的静态字段.您可以根据需要创建任意数量的对象实例,但Type任何给定类型实例只能有一个对象.