2009-08-13 57 views
9

我在想,从“object”继承的对象有多少内存并且没有字段/属性需要?我想方法不会。对 ?我在说.net对象。从c#对象中获取的内存

+0

好问题。我会说创造他们几百万,并看到之前和之后的内存差异。除非有人已经这样做了。 – 2009-08-13 16:24:04

+0

这就是为什么我问。我需要知道具有数百万个对象的应用程序的内存使用情况。所以32位应用程序的答案是所有字段+8字节的大小。 – 2009-08-13 17:28:19

回答

11

好了,因为这两个安德鲁和Guffa给了答案,我认为是错误的...

有对所有对象(在x86)的8个字节的开销,但有 12的最小尺寸字节。我不知道为什么...但它意味着,这两个类都采取每个实例12个字节:

public class OneField 
{ 
    private int field; 
} 

public class NoFields 
{ 
} 

测试:

using System; 

public class OneField 
{ 
    private int field; 
} 

public class NoFields {} 

public class Test 
{ 
    static void Main(string[] args) 
    { 
     int size = int.Parse(args[0]); 
     switch (args[1]) 
     { 
      case "NoFields": 
       TestNoFields(size); 
       break; 
      case "OneField": 
       TestOneField(size); 
       break; 
     } 
    } 

    static void TestNoFields(int size) 
    { 
     NoFields[] array = new NoFields[size]; 
     long start = GC.GetTotalMemory(true); 
     for (int i=0; i < size; i++) 
     { 
      array[i] = new NoFields(); 
     } 
     long end = GC.GetTotalMemory(true); 
     GC.KeepAlive(array); 
     Console.WriteLine("Size per instance: {0}", 
          (end-start)/(double)size); 
    } 

    static void TestOneField(int size) 
    { 
     OneField[] array = new OneField[size]; 
     long start = GC.GetTotalMemory(true); 
     for (int i=0; i < size; i++) 
     { 
      array[i] = new OneField(); 
     } 
     long end = GC.GetTotalMemory(true); 
     GC.KeepAlive(array); 
     Console.WriteLine("Size per instance: {0}", 
          (end-start)/(double)size); 
    } 
} 

这是丑陋的,因为我故意不去了任何泛型类型或其他任何可能导致问题的东西。一些测试运行:

>test 1000000 NoFields 
Size per instance: 12.000024 
>test 1000000 OneField 
Size per instance: 12.000024 
>test 1000 NoFields 
Size per instance: 12 
>test 1000 OneField 
Size per instance: 12 

(JITting开销等解释了为什么数量并不总是一个确切的整数 - 因此为什么我做除法的浮点数)。

测试与额外的int场演出使用量高达16,这证明它实际上是做一些合理的:)

+0

关于最小12字节的好处,但我认为问题的精神与从“System.Object”“继承”的信息有关。虽然在x86上是正确的,但第一个字段是“免费的”,但没有'System.Object'的开销,前3个字段本来可以是免费的:)但是,对于这个重要区别,还是+1。 – 2009-08-13 16:37:30

0

使用引用类型引起的唯一开销是类型对象指针为4个字节,同步块索引为4个字节。

总共8字节的开销。

3

一个对象除了它自己的数据外还有两个引用/指针。

因此,在32位系统上,对象占用8个字节,在64位系统上则占用16个字节。

更正信息:
正如Jon所说的,对象的最小尺寸是12个字节。我迄今发现的信息表明,GC需要这一点。

+4

不可以 - 由于某些原因,x86上的最小对象大小为12个字节,但您获得第一个字段为“免费”:) – 2009-08-13 16:32:42

+0

根据http://msdn.microsoft.com/zh-cn/magazine/cc163791 .aspx由于某种原因,GC要求该对象至少为12个字节。 – Guffa 2009-08-13 16:39:32