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出现了问题。

相关推荐
1-1=01 小时前
C# 数据结构和特殊类型
数据结构·c#·.net·.netcore
波力海苔夹心脆6752 天前
C# WPF 资源字典详解:ResourceDictionary、MergedDictionaries 与自定义控件案例
开发语言·c#·wpf·入门教程·resource·资源字典
AI导出鸭PC端2 天前
Perplexity批量导出没有PDF模式?AI导出鸭插件补上最后一块拼图
人工智能·pdf·c#·ai导出鸭
Risehuxyc2 天前
C# 选用更流行的语言版本
c#
淡海水3 天前
09-04-内存-Unity原生对象生命周期
unity·c#·游戏引擎·gc
吴可可1233 天前
富怡CAD二次开发指南
c#
1-1=03 天前
C# IO和序列化
c#·.net·.netcore
寂寞的船3 天前
【Unity Bug挑战】第10期 SerializeReference 内存泄漏之谜
unity·c#·游戏引擎·bug
CSharp精选营3 天前
从控制台到「会动手」的 AI:用 Semantic Kernel 搭应用(小白教程)
c#·.net·ai agent·semantickernel·functioncalling
宝桥南山4 天前
.NET 11 - 尝试一下Blazor中的新特性SupplyParameterFromTempData
microsoft·微软·c#·asp.net·.net·.netcore