2

我正在尝试诊断 C# 客户端应用程序中的内存泄漏。这个应用程序:

  • 在强化的 Windows 环境中运行
  • 与本地非托管第三方 API 通信
  • 通过 tcp 与服务器应用程序通信
  • 通过 waveOutWrite() 播放 wav 文件
  • 通过键盘供应商 dll 与自定义 USB 键盘集成
  • 接受用户输入以针对第三方 API 执行操作

根据客户配置,正常使用下的应用程序使用 50 到 100 MB 的内存。我们对该应用程序的最新更新运行了几周没有问题(确认在此期间没有内存问题)。然后,在没有任何代码更改或客户知道的客户端机器的任何更改的情况下,我们开始遇到以下情况:

  • 不受控制的、快速和/或逐渐的内存增长,直到抛出内存不足异常
  • 自定义键盘的间歇性延迟/不稳定响应
  • 当我们尝试播放音频时,waveOutWrite() 返回错误值 1(发生在内存接近最大使用量之前)

我使用 DebugDiag 1.2 来监视泄漏并得到完整的转储。分析的初步警告是:

DebugDiag 内存警告

转储显示本机堆中有 1.19 GB 的分配。634MB 来自Microsoft VC 运行时堆(私有),549MB 来自 DebugDiag LeakTrack 堆。634MB 堆有 44 个段,其中大部分为 15.81MB。

但是,分配报告似乎并不对应。按大小划分的最高分配是 992KB,也是数量为 3 的最高分配。以下是 634MB 堆的最高分配:

本机堆顶分配

我读错了吗?

转移到 WinDbg,如果我运行!heap -stat -h [634MBheapaddress] -grp B,我会得到:

group-by: BLOCKCOUNT max-display: 20  
size     #blocks    total     ( %) (percent of totalblocks)  
    44 9ea51 - 2a23d84  (44.14)  
    1a 1fba7 - 338ef6  (8.83)  
    18 1b3b8 - 28d940  (7.58)  
    10 16913 - 169130  (6.28)  
    12 1222c - 146718  (5.05)  
    22 d9d0 - 1ceda0  (3.79)  
    1c 9bea - 110d98  (2.71)  
    14 9197 - b5fcc  (2.53)  
    26 9115 - 15891e  (2.52)  
    20 6774 - cee80  (1.80)  
    24 5094 - b54d0  (1.40)  
    30 4b03 - e1090  (1.30)  
    78 4a81 - 22ec78  (1.30)  
    28 48d2 - b60d0  (1.27)  
    4 48bb - 122ec  (1.26)  
    58 48aa - 18fa70  (1.26)  
    1e 48a6 - 88374  (1.26)  
    2a 48a3 - beabe  (1.26)  
    16 4898 - 63d10  (1.26)  
    600 4884 - 1b31800  (1.26)  

如果我没看错的话,它会将顶部分配显示为 68 个字节并且有 650k 分配。这个对吗?如果是这样,这可能是一个潜在的问题,但仅代表 44MB - 远不及我显示为保留的 650MB。

无论哪种方式,我现在都不确定如何弄清楚这些分配是什么或者是什么造成了它们。我不知道为什么在我们这边没有任何代码更改的情况下这些问题就会开始发生。我不得不假设客户系统上发生了一些他们不知道的变化,这导致了我们代码中的一个错误,但到目前为止,我还没有找到根本原因。

任何帮助将不胜感激!

4

0 回答 0