通过IIS而不是通过控制台应用程序调用时,未损坏的代码会泄漏内存

时间:2013-08-22 21:16:34

标签: c# c wcf iis memory-leaks

我有一个用C语言编写的非托管库(内部也使用英特尔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以内。
  4. 我想我没有足够的重复点来发布图片,或者我可以发布性能监视器的屏幕截图。编写C代码的人认为这是一个IIS问题(或与Web服务C#代码有关),并指出当在独立应用程序中使用时,没有任何明显的泄漏。我使用的调试工具似乎另有说明。

    关于我可以做什么的任何建议,以确定问题所在?

1 个答案:

答案 0 :(得分:1)

如果ANTS内存分析器已识别出一个&#34;主要块&#34;内存被分配给非托管代码,你预计没有非托管内存使用,那么这将是一个开始调查的好地方。

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

如果在finally块的末尾强制执行GC集合会发生什么?您的ISS Web服务的行为是否与您的控制台应用程序类似?