GC.GetTotalMemory使用及其返回值

时间:2011-11-19 01:45:14

标签: c# garbage-collection

我有一个二进制文件保存在大小为15KB的磁盘上,但为什么它的内存大小总是只有4个字节

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个字节不足以存储一个hello world字符串,但为什么它不正确。 谢谢你的帮助。

4 个答案:

答案 0 :(得分:2)

假设通过将obj分配给数组o中的索引[1],它会花费大量的字节吗?您所做的只是分配参考。不仅如此,new Object[1000000]所做的只是创建一个数组(空间来关联1,000,000个对象和Object[]所需的内存。),而不是分配1,000,000个对象。我相信有人可以详细说明正在使用的内部数据结构以及出现4个字节的原因。

要意识到的关键是,为obj分配的o[1]不会为obj分配额外的内存。如果您在分配GC.GetTotalMemory之前尝试确定近似值obj,那么之后。在您调用第一个obj

之前,您已经分配了GC.GetTotalMemory

答案 1 :(得分:1)

一般情况下,当MSDN documentation 当前在托管内存中分配的字节数的最佳可用近似值时,它是依靠它获得准确值的坏主意: - )

除了开玩笑之外,如果您的对象'o'未在示例中第3行之后的函数中使用,则可能是在第3行和第4行之间收集它。只是猜测。

答案 2 :(得分:1)

首先,如果我使用编写的代码,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()是精确的,而不是必须的。

答案 3 :(得分:-2)

根据我的经验,marshal.sizeof()通常是获取对象真实大小的更好方法,而不是询问垃圾收集器。

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