如何在内存中获取对象大小?

Luk*_*kas 195 .net c# memory performance profiling

我需要知道我的对象在内存中消耗了多少字节(在C#中).例如,我Hashtable,或SortedList,或多少List<String>.

Rus*_*sby 163

这可能不准确,但它足够接近我

long size = 0;
object o = new object();
using (Stream s = new MemoryStream()) {
    BinaryFormatter formatter = new BinaryFormatter();
    formatter.Serialize(s, o);
    size = s.Length;
}
Run Code Online (Sandbox Code Playgroud)

  • 这将提供更多.它添加了DLL名称和版本,...**这不是计算对象大小的方法.** (114认同)
  • 我不认为有人关心获得确切的内存消耗量,但这很快并给出了一个很好的估计,因此"这可能不准确,但它足够接近我".为什么你不讨厌想出一些坚实的东西? (51认同)
  • 请注意,对象(o)必须标记为**serializable** (14认同)
  • 我同意这是_NOT_计算对象大小的好方法.序列化可能是熵的粗略估计,但没有提供有关内存消耗的有用信息.这是一个复杂的问题,没有简单的解决方案. (4认同)
  • C#中的列表预先分配给框架设计者决定使用的任何大小,然后在需要时增加.默认情况下,它可能类似于10个元素.因此,在添加足够的元素以分配更多内存之前,您不会注意到任何大小差异. (4认同)
  • 根据`rushonerok`,使用引用添加两个使代码工作是愚蠢的,所以我在注释中添加它们:`using System.IO;`和`using System.Runtime.Serialization.Formatters.Binary;` (3认同)
  • 我在使用项目填充之前和之后尝试了使用List <int>的方法,但它似乎无法返回相同的值 - 41.你知道它的共鸣吗? (2认同)
  • 我有同样的问题:列表的长度是41.流的整个内容是"\ 0\0\0 \0 \0\0\0\0\0\0\0\0\0\0\0\rSystem.Object\0\0\0\0\v",用`s.Position = 0检索; var sr = new System.IO.StreamReader(s); string str = sr.ReadToEnd();` (2认同)
  • 如果得到 41,则需要将对象 (object o = new object()) 替换为要测量的实际对象;)。这只是一个假人 (2认同)
  • @MatthieuCharbonnier你在记事本工作吗?大声笑.http://stackoverflow.com/questions/28193622/how-do-i-quickly-resolve-namespaces-in-visual-studio-2015 (2认同)

Run*_*tad 109

我不认为你可以直接得到它,但有几种方法间接找到它.

一种方法是使用该GC.GetTotalMemory方法来测量创建对象之前和之后使用的内存量.这不是完美的,但只要您控制应用程序的其余部分,您就可以获得您感兴趣的信息.

除此之外,您可以使用分析器来获取信息,或者您可以使用分析api来获取代码中的信息.但我觉得这并不容易.

请参阅了解C#中对象使用了多少内存?对于类似的问题.

  • 虽然"真实"的答案可能是"它无法完成",但更好的答案是为您提供可能的选择. (7认同)

Nil*_*han 28

非托管对象:

  • Marshal.SizeOf(object yourObj);

价值类型:

  • sizeof(object val)

托管对象:

  • 链接已死,您可以编辑答案吗? (2认同)
  • 我认为,有 1 位相关,但框架仍然使用 4 字节或 8 字节(取决于您的架构)....您可以在此处阅读详细说明 https://www.quora.com/In-C-why- bool 的大小是否为 1 字节-仅 1 位就足够 (2认同)

Ali*_*tad 27

好的,这个问题已经回答并接受了答案,但是有人让我把答案放到你那里去.

首先,不可能肯定地说.这是一个内部实现细节,没有记录.但是,基于另一个对象中包含的对象.现在,我们如何计算缓存对象的内存需求?

我之前在这篇文章中触及了这个主题:

现在,我们如何计算缓存对象的内存需求?好吧,正如大多数人所知,Int32和float是四个字节,double和DateTime是8个字节,char实际上是两个字节(不是一个字节),依此类推.字符串有点复杂,2*(n + 1),其中n是字符串的长度.对于对象,它将取决于它们的成员:只需总结其所有成员的内存需求,记住所有对象引用只是32位框上的4字节指针.现在,这实际上并不完全正确,我们没有处理堆中每个对象的开销.我不确定你是否需要关注这一点,但我想,如果你将使用大量的小物件,你将不得不考虑开销.每个堆对象的成本与其原始类型一样多,加上四个字节用于对象引用(在32位机器上,虽然BizTalk在64位机器上也运行32位),加上4个字节用于类型对象指针,我认为4同步块索引的字节数.为什么这个额外的开销很重要?好吧,让我们假设我们有一个有两个Int32成员的班级; 在这种情况下,内存要求是16个字节而不是8个字节.

  • 这不能回答OP的问题,我们应该如何衡量HashSet与List的大小? (2认同)

小智 17

以下代码片段应返回传递给它的任何对象的大小(以字节为单位),只要它可以序列化即可.我从Quixant的一位同事那里得到了这个解决在游戏平台上写入SRAM的问题.希望它有所帮助.感谢并感谢Carlo Vittuci.

/// <summary>
/// Calculates the lenght in bytes of an object 
/// and returns the size 
/// </summary>
/// <param name="TestObject"></param>
/// <returns></returns>
private int GetObjectSize(object TestObject)
{
    BinaryFormatter bf = new BinaryFormatter();
    MemoryStream ms = new MemoryStream();
    byte[] Array;
    bf.Serialize(ms, TestObject);
    Array = ms.ToArray();
    return Array.Length;
}
Run Code Online (Sandbox Code Playgroud)

  • 没为我工作。我没有将对象类定义为可序列化,并且抛出了“未标记为可序列化错误” (2认同)
  • 嗨@Kevin Hirst,我尝试用这个解析我的数据集来获取字节大小.它返回我的内存异常.我发现字节最大大小是2 GB?知道如何管理吗? (2认同)