2008-09-30 28 views

回答

0

你也可以做這樣的事情:

int startMem = GC.GetTotalMemory(true); 
YourClass c = new YourClass(); 
int endMem = GC.GetTotalMemory(true); 
int usedMeme = endMem - startMem; 
+0

我懷疑這是否正常工作。首先分配一個對象可以觸發一個新的垃圾回收循環。即使你調用了GetTotalMemory(true),someting可能會發生在影響結果的不同線程中。 – 2008-09-30 21:00:07

0

因爲.NET的垃圾收集的性質,它有點難以衡量多少內存是真正被使用。例如,如果您想測量類實例的大小,是否包含實例指向的實例使用的內存?

如果答案是否定的,加起來所有字段的大小: 使用反射,通過類的所有成員進行迭代;使用Marshal.Sizeof(member.Type)作爲typeof(ValueType)的任何類型.IsAssignableFrom(member.Type) - 這測量原始類型和結構,所有類型和結構都駐留在類的實例分配中。每個引用類型(任何不可賦值給valuetype的類型)都將採用IntPtr.Size。這有一些令人厭惡的例外,但它可能適用於你。

如果答案是肯定的,你有一個嚴重的問題。多個事物可以引用一個實例,所以如果'a'和'b'都指向'c',那麼RecursiveSizeOf(a) + RecursiveSizeOf(b)將大於SimpleSizeOf(a) + SimpleSizeOf(b) + SimpleSizeOf(c)

更糟糕的是,遞歸測量會導致您循環引用,或導致您無意測量的對象 - 例如,如果某個類正在引用一個互斥體,則該互斥體可能指向擁有它的線程。該線程可能指向其所有局部變量,這些變量指向一些C#框架結構......您可能最終會測量整個程序。

這可能有助於瞭解,像C#垃圾回收的語言是有點在它吸引的對象和存儲單位之間的區別的方式「模糊」(從完全非技術性的意義上)。這是很多減少編組規則的方法 - 編組規則確保您編組(或測量)的結構具有定義明確的內存佈局,因此具有明確定義的大小。在這種情況下,如果您打算使用Marhsal.SizeOf(),則應該使用定義良好的可編組結構。

另一個選項是序列化。這不會具體告訴你使用了多少內存,但它會給你一個關於對象大小的相對概念。但是,爲了序列化事物,它們必須有一個定義明確的佈局(因此有一個明確定義的大小) - 通過使該類適當地序列化來實現。

如果上述任何選項對您有吸引力,我可以發佈實施示例。

相關問題