2010-11-15 110 views
10

我有一個關於存儲數據及其內存佔用的基本問題。.NET內存大小

我有一個List<t>存儲我需要的基礎對象。類型t有一個int id來定義它,以及其他字段。

我現在有一本詞典。如果我創建了一個Dictionary<t, int>,其中t是該值的對象,那麼如果創建一個Dictionary<int, int>(即,存儲了該對象的副本),還是隻做了一次存儲再次存儲,內存分配是否會更高?

感謝

+2

我認爲你的意思解釋。關鍵是第一種類型,價值是第二種類型。 – 2010-11-15 20:22:02

+0

是的,這就是我的意思謝謝 – cab 2010-11-15 20:24:19

回答

13

那要看是什麼T是。如果T是引用類型(即,class),則只有引用將被存儲在字典中。如果T是值類型(struct),則將存儲副本。

+4

當然,指向一個真實物體的參考也會導致對該真實物體的單獨分配。 – 2010-11-15 20:21:16

1

只存儲對象的引用。內存分配將很小。

5

引用類型在您傳遞它們時不會創建重複的對象。在封面之下,基本上你會傳遞指針。因此,如果您有N個對象,則每個對象都有N個內存+引用每個對象所需的內存。這與這些引用的存儲容器無關,在您的情況下是字典。您將爲字典產生一些內存開銷,但如果您創建了另一個字典並將所有相同的對象放入其中,則只有2個字典內存成本加上內存中的一組對象。這是你使用參考類型的時候。

MyObject object = new MyObject(); // one object created in memory 
MyObject object2 = object; // still only one object created in memory, but we have two references now 

值類型在內存中始終是唯一的。因此,如果您創建System.Int32的字典並創建字典的副本,那麼您也將擁有字典中每個值的副本。

int myInt = 5; // one int created in memory 
int myInt2 = myInt; // two ints have been created in memory 

因此,讓我們弄清楚什麼內存塊被分配給特定的場景:

// two value types 
Dictionary<int, int> myDictionary1 = 
1 x Dictionary 
N x int <key> 
N x int <value> 

Dictionary<int, int> myDictionary1 + 
Dictionary<int,int> myDictionary2 (clone of 1) = 
2 x Dictionary 
2N x int <key> 
2N x int <value> 

// reference types 
Dictionary <string, MyObject> myDictionary3 = 
1 x Dictionary 
N x string Reference 
N x string instance (if they are all unique) 
N x Object Reference 
N x Object instance (if they are all unique) 

Dictionary <string, MyObject> myDictionary3 + 
Dictionary <string, MyObject> MyDictionary4 (clone of 3) = 
2 x Dictionary 
2N x string reference 
1N x string instance (if they are all unique) 
2N x Object reference 
1N x Object instance (if they are all unqiue) 

你的場景:

Dictionary<int, MyObject> myDictionary5 
1 X Dictionary 
N X key 
N X value reference 
N X value object 

Dictionary<int, MyObject> myDictionary5 + 
Dictionary<int, MyObject> myDictionary6 (clone of 5) = 
2 x Dictionary 
2N x key 
2N x value reference 
1N x value objects 
1

我假設你正在談論的特定集合類型System.Collections.Generic.Dictionary<K,V>

您沒有告訴我們您的類型't'是值類型還是引用類型。

如果它是參考類型,例如class T { int id; ...},則Dictionary<K,T>將保持對您添加的對象的引用。

如果它是值類型,例如struct T { int id; ...},然後Dictionary<K,T>將保留您添加的值的副本。

快樂的黑客攻擊。

0

正如我在其他問題中提到的在發展,你可以使用此代碼剖析內存:

bool forceFullCollection = false; 

Int64 valTotalMemoryBefore = System.GC.GetTotalMemory(forceFullCollection); 

//call here your bulk of Dictionary operations and objects allocations 

Int64 valTotalMemoryAfter = System.GC.GetTotalMemory(forceFullCollection); 

Int64 valDifferenceMemorySize = valTotalMemoryAfter - valTotalMemoryBefore; 

關於參數forceFullCollection:「如果forceFullCollection參數爲true,則此方法返回前等待很短的時間間隔同時系統收集垃圾並最終確定對象時間間隔的持續時間是一個內部指定的限制,取決於完成的垃圾收集週期的數量以及週期之間恢復的內存量的變化垃圾收集器不保證所有不可訪問的內存被收集。「 GC.GetTotalMemory Method

祝你好運!;)