2009-01-08 82 views
23

我試圖得到一個與.NET數據表相關聯的內存開銷以及表中的單個DataRows的句柄。
換句話說,數據表佔用的內存比僅僅存儲每列數據的正確類型的數組所需的內存多多少?
我想會有一些基本的表開銷,加上每列一些金額,然後再每行額外金額。因此,任何人都可以對這三種開銷中的每一種/這些開銷進行估計(以及我猜,解釋!)。在.NET DataTable中存儲數據的內存開銷是多少?

回答

22

那麼,別忘了DataTable店2? 3?數據的版本 - 原始和更新(可能是另一個?)。它也有很多參考,因爲它是基於單元的,並且對任何值類型進行裝箱。這將是難以量化的確切內存...

就個人而言,我很少使用DataTable - 鍵入POCO類是一個更合理的賭注在我看來。我不會使用數組(直接),但 - List<T>BindingList<T>或類似的會更常見。

作爲一個粗略的衡量標準,你可以創建很多表格等,並查看內存使用情況;例如,下面顯示了〜4.3因子 - 即4倍以上的昂貴的,但顯然對列的數目取決於很多VS行VS表等:

// takes **roughly** 112Mb (taskman) 
    List<DataTable> tables = new List<DataTable>(); 
    for (int j = 0; j < 5000; j++) 
    { 
     DataTable table = new DataTable("foo"); 
     for (int i = 0; i < 10; i++) 
     { 
      table.Columns.Add("Col " + i, i % 2 == 0 ? typeof(int) 
           : typeof(string)); 
     } 
     for (int i = 0; i < 100; i++) 
     { 
      table.Rows.Add(i, "a", i, "b", i, "c", i, "d", i, "e"); 
     } 
     tables.Add(table); 
    } 
    Console.WriteLine("done"); 
    Console.ReadLine(); 

VS

// takes **roughly** 26Mb (taskman) 
    List<List<Foo>> lists = new List<List<Foo>>(5000); 
    for (int j = 0; j < 5000; j++) 
    { 
     List<Foo> list = new List<Foo>(100); 
     for (int i = 0; i < 100; i++) 
     { 
      Foo foo = new Foo { Prop1 = "a", Prop3 = "b", 
       Prop5 = "c", Prop7 = "d", Prop9 = "e"}; 
      foo.Prop0 = foo.Prop2 = foo.Prop4 = foo.Prop6 = foo.Prop8 = i; 
      list.Add(foo); 
     } 
     lists.Add(list); 
    } 
    Console.WriteLine("done"); 
    Console.ReadLine(); 

(基於)

class Foo 
{ 
    public int Prop0 { get; set; } 
    public string Prop1 { get; set; } 
    public int Prop2 { get; set; } 
    public string Prop3 { get; set; } 
    public int Prop4 { get; set; } 
    public string Prop5 { get; set; } 
    public int Prop6 { get; set; } 
    public string Prop7 { get; set; } 
    public int Prop8 { get; set; } 
    public string Prop9 { get; set; } 
} 
+0

@Marc - 包含參考文獻無損AcceptChanges和朋友可以用來操縱正在存儲的版本庫存。 @Nick:底線是如果你想要光線,DataX不是你不想看的地方,而且你甚至不需要去測量。 爲什麼不寫一些測試來衡量? – 2009-01-08 15:29:06

+0

@Ruben - 處理它;-p – 2009-01-08 15:38:11

+0

Marc DataTable不包含值,它將類型數組中的值類型存儲起來。 – 2009-01-08 15:43:11

8

如果您沒有在列上定義索引,開銷很低。如果使用字符串緩存,則可以獲得相當低的內存佔用空間: 使用HashSet或Dictionary僅使用每個字符串值的1個字符串實例。這聽起來很奇怪,但是如果您從數據庫中獲取數據,並且您有多個具有相同字符串值的行(例如「ALFKI」),則字符串值相等,但字符串實例不是:字符串多次存儲記憶。如果您首先使用HashSet過濾出重複實例,則可以在數據表中的任意位置爲1個字符串值有效使用相同的字符串實例。這可以大大減少內存佔用。當然,如果字符串值已經在某個地方被靜態定義(所以不能從外部源讀取),這是不值得的。

4

這取決於您要存儲多少數據和哪種數據。顯然數據越多,內存越多。有一些與數據表有關的開銷,這使得它更加昂貴。您還需要了解大對象堆。如果您存儲超過85 kb的對象,則該對象將存儲在LOH中。這可能會對垃圾收集造成嚴重破壞,因爲它需要完整的收集。如果您準備測試它,請查看內存分析器以觀察數據表的內存佔用情況。

相關問題