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

相关推荐
csdn_aspnet4 小时前
C# 求n边凸多边形的对角线数量(Find number of diagonals in n sided convex polygon)
开发语言·算法·c#
武藤一雄9 小时前
C# 设计模式大全(第一弹|7种)
microsoft·设计模式·微软·c#·.net·.netcore
格林威10 小时前
Baumer相机锂电池极片裁切毛刺检测:防止内部短路的 5 个核心方法,附 OpenCV+Halcon 实战代码!
开发语言·人工智能·数码相机·opencv·计算机视觉·c#·视觉检测
向上的车轮11 小时前
熟悉C#如何转TypeScript——SDK与包引用
开发语言·typescript·c#
CSharp精选营12 小时前
Dispose 不释放?C# 资源泄漏的 3 种隐蔽场景排查
c#·资源泄漏
unicrom_深圳市由你创科技13 小时前
LabVIEW和C#在工业控制中的应用差异是什么?
fpga开发·c#·labview
唐青枫14 小时前
C#.NET Consul + Steeltoe 深入解析:服务注册发现、健康检查与微服务接入
c#·.net
DowneyJoy15 小时前
【Unity3D补充知识点】常用数据结构分析-集合(List<T>)
数据结构·unity·c#·list
格林威15 小时前
Baumer相机铝型材表面划伤长度测量:实现损伤量化评估的 5 个关键技术,附 OpenCV+Halcon 实战代码!
开发语言·人工智能·数码相机·opencv·计算机视觉·c#·工业相机
DowneyJoy16 小时前
【Unity3D补充知识点】常用数据结构分析-数组(Array)
数据结构·unity·c#