2009-08-13 55 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