2010-06-16 39 views
17

有沒有方法可以確定.NET中複雜對象的總大小?該對象由其他對象組成,並可能持有對其他複雜對象的引用。這個對象封裝的一些對象可能是POD,其他的可能不是。確定.NET中複雜對象大小的方法?

+1

對象是否可序列化? – 2010-06-16 21:12:18

+0

他們可能會:)對不起,因爲模糊,但我試圖使這個問題儘可能通用。 – Polaris878 2010-06-16 21:13:55

+0

什麼是C#/ .NET上下文中的「POD」?這是一個C++術語... – 2010-06-16 21:18:37

回答

10

你有什麼不是一個「複雜的對象」,它是一個對象圖。要確定它的總大小,你需要走這個圖 - 從一些根對象開始,並使用反射枚舉引用類型的字段並檢索它們的值(當然還有檢查循環)。

爲了得到圖中的一個特定對象的大小,請參閱this answer to a related question,但請注意,這是一個邪惡的黑客,完全不支持,可能會破壞(並且可能已經被打破),並可能導致批發小貓種族滅絕天上的球體。也就是說,沒有「非黑客」的方式來獲得準確的價值,因爲它是按定義的實現細節 - 你不應該有任何用處。爲了在調試/分析過程中找出應用程序的內存使用情況,黑客已經足夠好了。

+0

謝謝帕維爾。當我問這個問題時,我明白了複雜性,我只是好奇是否有人已經創建了一個計算此:)的對象圖遍歷 – Polaris878 2010-06-16 21:50:03

1

System.Runtime.InteropServices.Marshal.SizeOf()一槍。

+0

'Marshal.SizeOf()'不能考慮子對象的大小。 – drharris 2010-06-16 21:12:28

+0

請記住它是一個安全關鍵功能,所以不幸在很多情況下都不起作用。 – 2010-06-16 21:12:37

+1

它給出了對象的編組表示的大小,這不是完全相同的東西。 – 2010-06-16 21:39:04

2

Tricky ...

如果兩個對象指向同一個字符串變量,該怎麼辦?哪一個「擁有」字符串?這聽起來你需要模擬一個垃圾回收來獲得真正的答案。不完全重量輕。

+0

字符串在這裏不是一個好例子,因爲它是不可變的。 – 2010-06-16 21:24:19

+2

@保羅:不變性與此有什麼關係?重點是一個對象可以持有對從外部給予它的字符串的引用(例如文件名)。該字符串是否屬於該對象?它應該作爲其規模的一部分嗎? – 2010-06-16 21:38:37

4

簡單地說,沒有辦法知道。假設所有對象都是可序列化的,您可以使用BinaryFormatter將它們序列化成二進制blob,然後讀取它的大小。但是,這將包括一些元數據,並誇大實際的對象大小(但這將是一個合理的估計)。

對於值類型,您可以使用Marshal.SizeOf(),只有它沒有考慮到任何子對象。它會計算任何內部引用類型作爲指向它的指針的大小。

反思是另一種方式,但不會暴露任何私人成員佔用記憶。所以,除非我錯了,否則沒有辦法真正做到這一點。

1

以前在別處回答StackOverflow上:

Find size of object instance in bytes in c#

您需要引入不安全的代碼(由於其所需的指針操作) - 該代碼如下所示:

static unsafe int CalcSize(object obj) 
{ 
    RuntimeTypeHandle th = obj.GetType().TypeHandle; 
    int size = *(*(int**)&th + 1); 
    return size; 
} 

還記得將項目設置(Project-> Build選項卡)標記爲「允許不安全的代碼」。