c# - 通过 IIS 而不是通过控制台应用程序调用时,未镜像的代码会泄漏内存

标签 c# c wcf iis memory-leaks

我有一个用 C 编写的非托管库(内部也使用 Intel MKL 库),用于 WCF Web 服务。直接 PInvoke 用于调用公开的方法,库调用返回一个指向 double 组的指针,在对指针调用 free() 之前,该指针将复制到 C# 中的托管数组。

        double* xStars = null;
        metaData meta = new metaData();
        double[] output = null;
        bool hasError;
        string errorMessage;
        try
        {
            int errCode = someCFunction(...some params...
                &xStars,
                &meta);

            output = new double[meta.ArrayLength];
            for (int j = 0; j < meta.ArrayLength; j++)
            {
                output[j] = (xStars[j]);
            }
        }
        catch (Exception e)
        {
            WriteToEventLog();
            throw;
        }
        finally
        {
                            //Also in the C library
                            //Calls free(void *) 
            freeDoubleArray(&xStars);
            freeMeta(&meta);
        }

我有测试套件可以通过调用它

  • IIS 作为 Web 服务调用或
  • 运行所有其他业务逻辑但不作为 WS 运行的控制台应用
  • 一个较小的控制台应用程序,仅练习执行 PInvoke 的类

  • 通过控制台应用程序 (2) 运行时,使用的启动内存约为 50MB,并且即使在循环中调用底层 C 代码 100 次后仍保持相当稳定

  • 通过控制台应用程序 (2) 运行时,启动内存更小,约为 24MB,并且在 100 次调用后保持稳定
  • 通过 IIS 运行时,即使在服务启动时,内存使用量也约为 150-200 MB,并且每次调用 C 库时都会不断增加。最后到了 IIS 回收它的地步,因为正在使用的内存超出了设置的限制

它在 IIS 中的使用方式有什么问题?控制台应用程序 (2) 基本上是所有代码,但只是作为独立应用程序而不是 Web 服务运行。在这种情况下,应用程序不会出现任何内存泄漏或过度使用。

到目前为止我为了解根本原因所做的事情:

  1. 使用性能监视器来分析所有堆中的专用字节和 GC 字节。托管内存使用量在进程启动时不断攀升,并且在整个测试过程中几乎保持一条平坦的线,而使用的专用字节在第一次调用时飙升至 100 MB,并且在测试的每次迭代中都略有增加。
  2. 使用 Debug Diag 来分析非托管内存泄漏以及 IIS 工作进程使用的 500 MB 内存,Debug diag 表明 C 库有大约 43 MB 未释放内存,它认为这是泄漏,但没有解释泄漏的位置其余部分正在使用
  3. 我使用了 ANTS 内存分析器,它表明大部分内存是非托管的,托管内存使用情况最差,在 30 MB 以内。

我想我没有足够的代表点来发布图片,或者我可以发布性能监视器的屏幕截图。编写 C 代码的人认为这是 IIS 问题(或者与 Web 服务 C# 代码有关),并指出在独立应用程序中使用时,没有任何明显的泄漏。我使用的调试工具似乎表明情况并非如此。

关于我下一步可以做什么来查明问题出在哪里,有什么建议吗?

最佳答案

如果 ANTS 内存分析器发现内存的“主要 block ”被分配给非托管代码,而您预计不会使用非托管内存,那么这将是开始调查的好地方。

如果取消注释“freeDoubleArray(&xStars);”会发生什么和“freeMeta(&meta);”?您在控制台应用程序中是否获得了与 ISS Web 服务类似的行为?

如果在finally block 末尾强制进行GC 收集,会发生什么情况?那么您的 ISS Web 服务的行为方式是否与控制台应用程序类似?

关于c# - 通过 IIS 而不是通过控制台应用程序调用时,未镜像的代码会泄漏内存,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/18390996/

相关文章:

c# - 如何在 MAUI 中删除操作栏

c#将事件参数从另一个类传递给主类

c - C 中的冒泡排序显示段错误

c - 事物被错误地读入数组

wcf - 客户端 WCF DataContract 具有来自服务的空/空值

c# - Windows.Devices.Geolocation 需要什么 dll?

jquery - 从网络/TCP/HTTP 连接的角度来看,Node.js 是如何工作的? WCF 可以模拟这个吗?

c# - 动态转换为接口(interface)时出现 InvalidCastException

c# - 使用 Azure ARM 模板和 C# 进行部署时设置调试级别

粘贴在浏览器地址栏中有效的相同网址时,curl 不起作用