我在 WP7 项目上运行了一个 C# XNA,我发现它在屏幕更改之间占用了内存并且没有返回它,最终导致内存不足异常。
我看了又看,但我一辈子都找不到这段记忆的去向。
有什么方法可以找出内存在哪里被使用以及为什么它没有被归还给设备?
谢谢你的帮助!
我在 WP7 项目上运行了一个 C# XNA,我发现它在屏幕更改之间占用了内存并且没有返回它,最终导致内存不足异常。
我看了又看,但我一辈子都找不到这段记忆的去向。
有什么方法可以找出内存在哪里被使用以及为什么它没有被归还给设备?
谢谢你的帮助!
在项目的 Windows 版本上使用 Microsoft 的CLR Profiler for .NET Framework 4 (免费)。
使用它,您可以获得项目内存分配的时间表。或者您可以检查堆本身。它为您提供按类型分配的所有内容的列表。您可能会看到您过度分配的对象,从那里您可以调出该类型或该时间范围的分配图。这将显示哪些函数分配了这些对象。
这是一个随机的博客条目,其中包含一些关于 CLR Profiler 的屏幕截图和讨论。(不完全是您将使用它做什么,但如果您以前从未使用过 CLR Profiler,这是一个有用的介绍。)
但是:因为您使用的是 XNA,并且您通常必须非常努力地让 C# 耗尽托管内存,所以您可能会耗尽非托管内存。Dispose()
在您停止使用您创建的图形或声音对象之前,您是否有没有调用的地方?我已经多次讨论过这个细节 。
所以请注意,如果您在 CLR Profiler 中显示了许多非常小的对象 - 它们实际上可能正在使用大量的非托管内存。
你可以试试Redgate 的 ANTS 内存分析器(但它很贵),我不确定是否将它与 WP7 一起使用,但它适用于 C#。
有一个免费试用版,因此您可以使用它来帮助定位问题。
Eqatec有一个适用于 WP7 的分析器。它不是内存分析器,但我会尝试看看它显示了什么。它可能有助于为您指明正确的方向。
使用.NET Framework 2.0 的 CLR Profiler。默认情况下,XNA 4.0 不支持它,但 Crappy Coding 上的 Dave 有一个解决方法。
我使用的是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
它的优点不在我的脑海中: