2010-11-15 113 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

祝你好运!;)