如何在C#中找到内存消耗的位置?

时间:2011-03-21 22:41:27

标签: c# memory windows-phone-7 xna xna-4.0

我在WP7项目运行时有一个C#XNA,我发现它在屏幕更改之间占用了内存而没有返回它,最终导致了一个outofmemoryexception。

我看了看,但我不能为我的生活找到这段记忆的去向。

有什么方法可以找出内存的使用位置以及为什么没有将内存返回给设备?

感谢您的帮助!

6 个答案:

答案 0 :(得分:6)

在项目的Windows版本上使用Microsoft的CLR Profiler for .NET Framework 4(免费)。

使用此功能,您可以获得项目内存分配的时间表。或者您可以检查堆本身。它为您提供按类型分配的所有内容的列表。您可能会看到过分分配的对象,从那里您可以为该类型或该时间范围调出分配图。这将显示分配这些对象的功能。

这是一个random blog entry,其中包含一些CLR Profiler的屏幕截图和讨论。 (不完全是你将用它做什么,但如果你之前从未使用过CLR Profiler,这是一个有用的介绍。)

然而:因为您使用的是XNA,并且您通常必须尝试真的很难让C#用完托管内存,否则您可能已经用完< em> unmanaged 内存。在您停止使用您创建的图形或声音对象之前,是否有某个地方没有调用Dispose()?我已经讨论了这个a couple of times的详细信息。

所以请注意,如果你在CLR Profiler中出现了很多非常小的对象 - 实际上它们可能会占用大量的非托管内存。

答案 1 :(得分:2)

您可以尝试Redgate's ANTS Memory Profiler(但需要付费),我不确定是否将它与WP7一起使用,但它适用于C#。

有免费试用版,因此您可以使用它来帮助找到问题。

答案 2 :(得分:1)

Eqatec有一个与WP7配合使用的分析器。它不是一个内存分析器,但我试着看看它出现了什么。它可能有助于指明您正确的方向。

答案 3 :(得分:1)

coding4fun toolkit包含一个内存计数器,可帮助跟踪应用程序的内存使用情况。 Here's文档和article证明其使用。

答案 4 :(得分:1)

使用CLR Profiler for the .NET Framework 2.0。默认情况下,XNA 4.0不支持它,但Crappy Coding上的Dave有workaround

答案 5 :(得分:0)

我使用的是Mono profiler。它有各种选择;最简单的用法是

mono --profile=log program.exe

然后,在program.exe退出后,它会留下一个分析器文件(默认情况下为output.mlpd,并阅读所收集的信息使用:

mprof-report output.mlpd

E.g。我做mprof-report output.mlpd | vim -

默认情况下,它会收集一堆不同的信息。在输出的最开始(给定默认设置),您将看到按«已分配»列排序的功能表,例如剪辑:

Allocation summary
  24      Bytes      Count  Average Type name
  25    7357392     306558       24 System.IntPtr
  26    6677904     139123       48 System.Collections.ArrayList.ArrayListEnumeratorSimple
  27    5842736     136185       42 Mono.Unix.Native.Syscall._pollfd[]
  28    3078176      49566       62 System.Byte[]
  29    2574504      38057       67 System.String
  30     908320      14803       61 System.Int32[]
  31     719984       5294      136 Mono.Globalization.Unicode.SortKeyBuffer

我的想法有其优点:

  • 它是跨平台的,因此您可以轻松地在GNU / Linux和Mac上分析.net RAM分配。
  • 它是由.net的创建者和最大用户开发的 - Microsoft。之前它是由Xamarin开发的,但是MS买了它们,现在他们在主要的Mono页面上提到过。