2011-11-19 124 views
2

我有一個二進制文件保存大小15KB的磁盤,但爲什麼它的內存大小始終只有GC.GetTotalMemory使用,它的返回值

long mem1=GC.GetTotalMemory(false); 
Object[] array= new Object[1000000]; 
array[1]=obj; // obj is the object content of the file before it is saved on disk 
long mem2=GC.GetTotalMemory(false); 
long sizeOfOneElementInArray=(mem2-mem1)/1000000; 

我說錯了一些地方的4個字節。我認爲這是不正確的,因爲4個字節不足以存儲hello世界字符串,但它爲什麼不正確。 感謝您的幫助。

+0

這與磁盤上的文件有什麼關係? –

+0

在將對象作爲二進制文件保存到磁盤之前,它是一個對象,即obj,我試圖查看它消耗了多少內存。它是4個字節。你認爲我正確的檢索記憶體的方式嗎? – PointedC

+0

@PointedC,你所擁有的代碼根本不會測量'obj'。它只測量「o」。 – svick

回答

1

一般來說,當MSDN documentation說着什麼一個數字,是目前在託管內存分配字節數的最好的逼近這是一個壞主意,依靠它的精確值:-)

所有的開玩笑,如果你的對象'o'沒有在你的例子中的第3行後面的函數中使用,它可能是第3和第4行之間收集。只是猜測。

2

假設通過將obj賦值給數組o中的索引[1],它將需要大量的字節?你所做的只是分配一個參考。不僅如此,而且new Object[1000000]所做的只是創建一個數組(空間來關聯1,000,000個對象和Object[]所需的內存),而不是分配1,000,000個對象。我相信有人可以詳細闡述正在使用的內部數據結構以及爲什麼顯示4個字節。

要實現的關鍵是分配的objo[1]沒有爲obj分配額外的內存。如果您正在嘗試確定在分配obj之前近似呼叫GC.GetTotalMemory,則在之後。在您的測試,你打電話之前,首先GC.GetTotalMemory

+0

4個字節是32位體系結構上引用(指針)的大小。 – svick

+0

+1。是的,問題中的代碼發現在特定平臺上(x86是VS 2010的默認設置),對象引用的大小爲4個字節。 –

1

首先obj已經被分配了,如果我用書面的代碼中,x 0對我來說,因爲o不轉讓後使用,所以GC可以收集它。以下假定不收集o(例如,在方法結束時使用GC.KeepAlive(o))。

讓我們來仔細看看了每個代碼的兩個重要的幾行做(假設32位體系結構):

Object[] o = new Object[1000000]; 

此行分配1000000 * 4 + 16個字節。數組中的每個元素都需要4個字節,因爲它是一個對象的引用(指針)。 16個字節是數組的開銷。

o[1] = obj; 

此行改變o引用到obj的參考文獻中的一個。該行分配恰好0字節。

我不確定爲什麼你對結果感到困惑。它必須是4,除非代碼的前面部分有一些未引用的對象。在這種情況下,它可能小於4(甚至是負數)。當然,如果這是一個多線程應用程序,其結果可能幾乎任何東西,這取決於其他線程所做的。

而這一切都假設GetTotalMemory()是精確的,它並不是必須的。

-1

根據我的經驗,marshal.sizeof()通常是比獲取垃圾收集器更好的獲取對象真實大小的方法。

http://msdn.microsoft.com/en-us/library/y3ybkfb3.aspx

+0

'Marshal.SizeOf()'用於獲取對象的封送格式的大小,它不必與普通大小相同。 (我不是說'GetTotalMemory()'是正確的方法,但是'Marshal.SizeOf()'顯然不是。) – svick