C#调用C++ dll异常排查

基本情况

最近在做的一款程序,长时间运行总会出现莫名的问题。有时是自动关闭,有时程序报错,有时调用的dll异常......

提出假设------dll内存泄漏

由于开始与C++组合作时,使用其提供的dll出现过数据读写时异常(内存操作异常),于是怀疑他们提供的dll有内存泄漏。于是想通过日志或其它方法来确认这个猜测。

如何验证是C++ dll的问题?

通过记录当前Process的Memory情况,确认在调用dll时内存的基本情况,然后与不调用dll的内存情况进行比对,基本就能确认到底是不是dll的内存操作有问题。

日志数据分析

记录进程内存情况与电脑内存运行情况

以下为记录内存状况的Function:

cs 复制代码
  private static void MemoryLog()
  {
      Task.Run(async () =>
      {
          string appName = typeof(App).Namespace;
          var mb = 1024 * 1024;
          while (true)
          {
              Process currentProcess = Process.GetCurrentProcess();
              var working = currentProcess.PagedMemorySize64;
              await Task.Delay(1000);
              NlogHelper.Logger.Trace($"MemoryLog Working Set: {currentProcess.WorkingSet64 / mb} MB, PeakWorking Set: {currentProcess.PeakWorkingSet64 / mb} MB, Private Memory: {currentProcess.PrivateMemorySize64 / mb} MB, PagedMemory: {currentProcess.PagedSystemMemorySize64 / mb}MB, PeakPagedMemory:{currentProcess.PeakPagedMemorySize64 / mb}MB");
              NlogHelper.Logger.Trace($"MemoryLog {Performance.GetMemInfo()}");
          }
      });
  }

上述代码中,working memory为进程分配的物理内存,private memory 为进程的专用内存(此为最关键,虚拟内存),详细参考API:Process 类 (System.Diagnostics) | Microsoft Learn

下述为Performance中的GetMemInfo方法:

cs 复制代码
  public static string GetMemInfo()
  {
      MEMORY_INFO mi = GetMemoryStatus();
      return string.Format(", \t\t\t{0},{1:f0}%", FormatSize(mi.ullTotalPhys - mi.ullAvailPhys), mi.dwMemoryLoad);
  }


        /// <summary>
        /// 获得当前内存使用情况
        /// </summary>
        /// <returns></returns>
        public static MEMORY_INFO GetMemoryStatus()
        {
            MEMORY_INFO mi = new MEMORY_INFO();
            mi.dwLength = (uint)Marshal.SizeOf(mi);
            GlobalMemoryStatusEx(ref mi);
            return mi;
        }

        [DllImport("kernel32.dll")]
        [return: MarshalAs(UnmanagedType.Bool)]
        public static extern bool GlobalMemoryStatusEx(ref MEMORY_INFO mi);

注意:在记录日志时最好记录为一行,同时数据之间以空格或逗号或tab分离等分隔符分离,以方便数据分析时在表格中使用分隔符进行分列统计。

日志图表化

通过日志记录发现,专用内存在不断增长:

也就是说一定是存在内存泄漏了。

而在不调用dll时运行50次的内存情况则如下:

也就是说在程序运行期间内C#内存使用情况是基本稳定的,不会出现不断增长的情况。

以上基本可以确认是C++的dll出现了问题。

相关推荐
IT规划师4 小时前
开源 - Ideal库 - 常用枚举扩展方法(一)
开源·c#·.net core·ideal库·枚举转换
NetX行者10 小时前
.NET 9震撼来袭:基于.NET 8的五大功能亮点,引领开发新潮流
开发语言·microsoft·c#·.netcore
张某布响丸辣10 小时前
HTTP状态码详解
java·网络·python·网络协议·http·c#
飞舞的哈哈11 小时前
C# 有趣的小程序—桌面精灵详细讲解
c#
Skyshin3413 小时前
C# IEnumerator,IEnumerable ,Iterator
开发语言·c#
ling1s13 小时前
C#核心(7)索引器
开发语言·c#
LKID体14 小时前
win32com库基于wps对Word文档的基础操作
c#·word·wps
金蝶软件小李14 小时前
vector和docker的区别?
开发语言·docker·c#
金蝶软件小李16 小时前
图像处理椒盐噪声
开发语言·图像处理·算法·计算机视觉·c#
小吴同学·17 小时前
(实战)WebApi第13讲:怎么把不同表里的东西,包括同一个表里面不同的列设置成不同的实体,所有的给整合到一起?【前端+后端】、前端中点击标签后在界面中显示
c#·.netcore·.net core