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

相关推荐
IT90901 小时前
C#软件授权注册码模块源码及机器码注册码功能
c#·软件开发
WAZYY061912 小时前
C#实现PDF合并、裁剪功能
开发语言·pdf·c#·pdf合并·pdf工具·pdf切割
开开心心就好12 小时前
文档格式转换软件 一键Word转PDF
开发语言·前端·数据库·pdf·c#·word
小码编匠15 小时前
WinForm 中集成 NLog 实现全局异常处理
后端·c#·.net
我不是程序猿儿16 小时前
【C#/Cpp】CLR项目搭建的内联和托管两选项
开发语言·microsoft·c#
技术支持者python,php16 小时前
C#,ModbTCP和ModbRTU通讯
开发语言·c#
chillxiaohan17 小时前
AbpvNext问题记录——post接口,接收前端发送的空串转换数字异常问题。
c#
爱编程的鱼1 天前
C# 数组&C# 多维数组
数据结构·算法·c#
techdashen1 天前
性能比拼: .NET (C#) vs. Fiber (Go)
golang·c#·.net
code bean1 天前
【C#】获取不重复的编码(递增,非GUID)
开发语言·c#