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

C# 如何在内存中获取对象大小?,c#,.net,performance,memory,profiling,C#,.net,Performance,Memory,Profiling,我需要知道我的对象在内存中消耗了多少字节(用C#)。例如,我的哈希表,或分类列表,或列表非托管对象的数量: Marshal.SizeOf(objectyourobj) 值类型: sizeof(对象值) 托管对象: 似乎没有直接的方式获取托管对象,参考: 我认为你不能直接得到它,但有几种方法可以间接找到它 一种方法是使用该方法测量创建对象前后使用的内存量。这并不完美,但只要您控制应用程序的其余部分,就可以获得您感兴趣的信息 除此之外,您可以使用探查器获取信息,也可以使用获取代码中的信息

我需要知道我的对象在内存中消耗了多少字节(用C#)。例如,我的
哈希表
,或
分类列表
,或
列表

非托管对象的数量:

  • Marshal.SizeOf(objectyourobj)
值类型:

  • sizeof(对象值)
托管对象:

  • 似乎没有直接的方式获取托管对象,参考:

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

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

      除此之外,您可以使用探查器获取信息,也可以使用获取代码中的信息。但我认为这并不容易使用

      有关类似问题,请参阅。

      在调试模式下

      加载SOS


      并执行dumpheap命令。

      这可能不准确,但对我来说已经足够接近了

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

      以下代码片段应该返回传递给它的任何对象的大小(以字节为单位),只要它可以序列化。 我从Quixant的一位同事那里得到这封信,是为了解决在游戏平台上向SRAM写信的问题。希望有帮助。 感谢卡洛·维图奇

      /// <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;
      }
      
      //
      ///计算对象的长度(以字节为单位)
      ///并返回大小
      /// 
      /// 
      /// 
      私有int GetObjectSize(对象TestObject)
      {
      BinaryFormatter bf=新的BinaryFormatter();
      MemoryStream ms=新的MemoryStream();
      字节[]数组;
      序列化(ms,TestObject);
      数组=ms.ToArray();
      返回数组。长度;
      }
      
      好的,这个问题已经得到了回答,答案也被接受了,但是有人让我把我的答案放在这里

      首先,不可能确定。这是一个内部实施细节,没有记录。但是,基于其他对象中包含的对象。现在,我们如何计算缓存对象的内存需求

      我以前曾在本书中提到过这个问题:

      现在,我们如何计算缓存的内存需求 物体?你们大多数人都知道,Int32和float是4 字节,双字节和DateTime 8字节,char实际上是两个字节(不是 一个字节),依此类推。字符串稍微复杂一点,2*(n+1),其中n 是字符串的长度。对于对象,它将取决于它们的 成员:只需总结其所有成员的内存需求, 记住所有的对象引用都只是32位上的4字节指针 比特盒。现在,这其实并不完全正确,我们没有注意到 堆中每个对象的开销。我不确定你是否需要 我很担心,但我想,如果你会使用很多 对于小的物体,你必须把头顶的部分考虑进去 考虑每个堆对象的成本与其基本类型相同, 加上四个字节用于对象引用(在32位机器上,尽管 BizTalk也在64位计算机上运行32位(另加4个字节) 键入objectpointer,我认为同步块索引有4个字节。为什么? 这额外的开销重要吗?好吧,让我们想象一下我们有一个 拥有两名Int32成员的类;在这种情况下,内存需求为 16字节,而不是8字节


      任何容器都是一个相对较小的对象,它包含对实际容器对象之外的某些数据存储(通常是数组)的引用,而这反过来又包含对添加到容器中的实际对象的引用。所以一个列表需要多少内存这个问题甚至没有很好的定义-列表对象本身的大小,列表对象分配的内存,列表中所有内容的总大小和收集列表时将释放的内存量都是不同的值。请参阅我创建的测试应用程序中的基准测试:这将投入更多。它添加了DLL名称和版本。。。这不是计算物体大小的方法。我同意这不是计算物体大小的好方法。序列化可能是对熵的粗略估计,但没有提供有关内存消耗的有用信息。这是一个复杂的问题,没有简单的解决方案。我认为没有人关心内存消耗的确切数量,但这很快,并给出了一个很好的估计,因此“这可能不准确,但对我来说已经足够接近了”。你们这些讨厌的人为什么不拿出一些可靠的东西呢?C#中的列表预先分配给框架设计师决定使用的任何大小,然后在需要时增加。默认情况下,它大概是10个元素。因此,在添加足够的元素以需要分配更多内存之前,您不会注意到任何大小差异。请注意,必须将对象(o)标记为SerializableDot不适用于我。我没有将对象类定义为可序列化的,它抛出了一个“未标记为可序列化错误”Hi@Kevin Hirst,我尝试用它解析我的数据集以获得字节大小。它返回我内存不足的异常。我发现字节的最大大小是2GB?你知道如何管理吗?@Worgon,除了调查目的,你真的需要知道你的数据集有多大吗?我宁愿往上想,消除这种必要性。如果您坚持,您可能会考虑测量特定的数据行大小,或者使用上面提到的
      GC.GetTotalMemory
      方法。@Worgon 2GB是应用程序的.NET环境的内存大小。您无法轻松管理它-只在其他堆中存储大对象。这是投票数最多的答案的副本,这有问题,但此代码有几个问题,首先二进制格式化程序速度慢,但随后有一个没有使用的内存流,然后将数据的副本存储到数组中。而“真正”的答案可能是“无法完成”更好的答案是给你一个可能的选择