7

我在 WP7 项目上运行了一个 C# XNA,我发现它在屏幕更改之间占用了内存并且没有返回它,最终导致内存不足异常。

我看了又看,但我一辈子都找不到这段记忆的去向。

有什么方法可以找出内存在哪里被使用以及为什么它没有被归还给设备?

谢谢你的帮助!

4

6 回答 6

6

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

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

这是一个随机的博客条目,其中包含一些关于 CLR Profiler 的屏幕截图和讨论。(不完全是您将使用它做什么,但如果您以前从未使用过 CLR Profiler,这是一个有用的介绍。)

但是:因为您使用的是 XNA,并且您通常必须非常努力地让 C# 耗尽托管内存,所以您可能会耗尽非托管内存。Dispose()在您停止使用您创建的图形或声音对象之前,您是否有没有调用的地方?我已经多次讨论过这个细节

所以请注意,如果您在 CLR Profiler 中显示了许多非常小的对象 - 它们实际上可能正在使用大量的非托管内存。

于 2011-03-22T07:28:39.207 回答
2

你可以试试Redgate 的 ANTS 内存分析器(但它很贵),我不确定是否将它与 WP7 一起使用,但它适用于 C#。

有一个免费试用版,因此您可以使用它来帮助定位问题。

于 2011-03-21T22:44:34.393 回答
1

Eqatec有一个适用于 WP7 的分析器。它不是内存分析器,但我会尝试看看它显示了什么。它可能有助于为您指明正确的方向。

于 2011-03-21T23:03:35.873 回答
1

使用.NET Framework 2.0 的 CLR Profiler。默认情况下,XNA 4.0 不支持它,但 Crappy Coding 上的 Dave 有一个解决方法

于 2011-03-22T02:10:54.507 回答
1

coding4fun工具包包含一个内存计数器,可帮助跟踪应用程序的内存使用情况。这是文档和一篇演示其用法的文章。

于 2011-03-21T23:45:12.330 回答
0

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

mono --profile=log program.exe

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

mprof-report output.mlpd

例如我做mprof-report output.mlpd | vim -

默认情况下,它收集一堆不同的信息。在输出的最开始(给定默认设置),您将看到按 «allocated» 列排序的函数表,例如一个片段:

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 的创建者和最大用户——微软开发的。早些时候它是由 Xamarin 开发的,但 MS 买了它们,现在它们在 Mono 主页上提到。
于 2016-07-28T10:22:49.370 回答