2016-11-15 65 views
1

有一个拥有数十万C#行的大型商业WPF应用程序。我最近被分配给它。该应用程序还使用(最新版本的)第三方组件(知名的第三方组件提供商,我不想列出它们)。Windows 10上的WPF应用程序中的内存泄漏

内存泄漏只发生在某些合作伙伴。他们在早上启动应用程序,并在完全吃完内存之前使用它几个小时,最终变得非常慢,以至于不得不重新启动它(每天几次)。他们有Windows 10机器(但这可能没有意义)。我无法重现我身边的泄漏。

合作伙伴允许我发布特殊版本的应用程序,但不允许使用Memory Profiler(他们希望使用该应用程序进行制作,并且所连接的Profiler会降低速度)。所以我的想法是:让我们发布一个特殊版本,记录所有内容,包括用户点击和处理“可疑”GC根。正如我所说,我不知道我必须调试的代码,所以我用内存分析器识别了可能泄漏的GC根。 (是的,我列出了可能的罪魁祸首,如依赖属性,静态列表等,但目前还没有运气。正如我所说的,我不太了解源代码,但我可以访问它,可以修改它的任何部分。)

我实际上正在编写一个编程问题:除了用户行为和访问静态变量之外,还应该记录什么?也许我应该在每次用户操作后记录空闲内存。什么是适合.NET的方法?

合作伙伴在重新启动应用程序之前会复制并发送日志文件。

+0

我发货我用[dotTrace的 “自我分析” API]申请(https://www.jetbrains.com/help/profiler/2016.2/Profiling_Guidelines__Advanced_Profiling_Using_dotTrace_API.html)。用户可以设置复选框来启用/禁用性能分析。似乎只有_performance_分析,而不是_memory_分析。 –

+0

我认为最好的办法不是记录所有内容,而是在应用程序变慢时收集内存转储。然后让客户端将该内存转储传递给您并进行分析。 – Evk

+0

@Evk:有没有API方法?这些合作伙伴并不是真正的IT人员,他们希望在进行“分析”或日志记录的同时,使用应用程序正常工作。所以他们可以找到日志txt文件,但不能创建转储。他们也不想叫我来创建一个内存转储。 (其他问题:应用程序的某些部分写得不太好,所以内存有时会在我自己的测试中增长很多,但是过了几分钟后,出现了一个大的GC,一切都恢复正常,不在他们的机器上......) –

回答

6

我想在此突出几点让您选择正确的曲目。

  1. 如果有内存泄漏的可能性很小,这是Windows 10特定的 问题。您应该能够在您的 开发PC中重现相同的问题。

  2. 通过编写 日志,内存泄漏(及其原因)不容易跟踪。你需要知道什么确实持有这种不断增长的实例。

  3. 我会在本地(在您的开发电脑中)使用正确的内存分析工具(例如:ANTS Memory profiler)并尝试重现 问题。

你不需要很好的理解代码库来检测内存泄漏。检测泄漏并找到根本原因是这里80%的任务。如果你知道什么物体在增长,什么物体在它上面,它可能不是那么难以修复它。

基本上你需要做的是。

  • 获取一个好的内存分析器(您可以使用试用版)。
  • 找到您的客户经常使用的区域/功能。
  • 运行应用程序并获取基本内存快照。
  • 几次执行相同的功能并拍摄另一个内存快照。将快照与基础快照进行比较,查看内存中是否有任何增长的实例。你应该能够看到物体保持图,它显示了如果有任何物体保持在那些生长的实例上。
  • 当您进行内存快照时,通常会执行内存分析器 GC.收集并清除内存中所有不必要的实例。因此,为了测试应用程序是否存在内存泄漏,您不需要进行任何代码更改。
  • 一次测试一个功能。
+0

1)很高兴知道。许多合作伙伴都使用这种方式,泄漏只发生在几个似乎拥有Win10的合作伙伴身上。他们使用该应用程序与其他应用程序相同的功能。但我同意。他们遇到泄漏可能是因为他们更密集地使用了相同的功能(并且泄漏也可能出现在其他人身上,他们只是没有注意到)。 2)我明白了。实际上,日志将有助于重现客户的实际行为。从他们的屏幕录像中,我试图重现它,但似乎没有发生明显的泄漏。尽管如此,我会用匿名保留图更新我的初始帖子。 –