C# 当通过IIS而不是控制台应用程序调用时,未老化的代码会泄漏内存

C# 当通过IIS而不是控制台应用程序调用时,未老化的代码会泄漏内存,c#,c,wcf,iis,memory-leaks,C#,C,Wcf,Iis,Memory Leaks,我有一个用C编写的非托管库(内部也使用Intel MKL库),它用于WCF web服务。直接向上PInvoke用于调用公开的方法,库调用返回指向双数组的指针,该双数组在对指针调用free()之前复制到C#中的托管数组 double* xStars = null; metaData meta = new metaData(); double[] output = null; bool hasError; string

我有一个用C编写的非托管库(内部也使用Intel MKL库),它用于WCF web服务。直接向上PInvoke用于调用公开的方法,库调用返回指向双数组的指针,该双数组在对指针调用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);
        }
double*xStars=null;
metaData meta=新元数据();
double[]输出=null;
布尔误差;
字符串错误消息;
尝试
{
int errCode=someCFunction(…某些参数。。。
&斯特拉斯,
&元);
输出=新的双精度[元阵列长度];
对于(int j=0;j
我有测试套件,可以通过

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

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

  • 当通过控制台应用程序(2)运行时,启动内存甚至更小,大约24MB,并且在几个100次呼叫后保持稳定
  • 当通过IIS运行时,即使在服务启动时,内存使用量也在150-200 MB左右,并且每次调用C库时都会不断增加。它最终达到了IIS回收它的程度,因为正在使用的内存超过了设置的限制
IIS中使用它的方式有什么问题?控制台应用程序(2)基本上是所有代码,但只是作为独立应用程序而不是web服务运行。在这种情况下,应用程序不会出现任何内存泄漏或过度使用

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

  • 使用性能监视器分析所有堆中的专用字节和GC字节。托管内存的使用在进程启动时会上升,在整个测试过程中几乎保持不变,而私有字节的使用在第一次调用时会达到两个100MB的峰值,并且在测试的每次迭代中都会略微增加
  • 使用Debug Diag分析非托管内存泄漏,在IIS工作进程使用的500 MB内存中,Debug Diag表示C库有大约43 MB的未释放内存,它认为这是一个泄漏,但没有解释其余内存的使用位置
  • 我使用了ANTS内存分析器,它表明大部分内存是非托管的,托管内存的使用率最差也在30 MB以内
  • 我想我没有足够的代表点数来发布图片,或者我本可以发布性能监视器的屏幕截图。编写C代码的人认为这是一个IIS问题(或与web服务C代码有关),并指出在独立应用程序中使用时,没有任何明显的泄漏。我使用的调试工具似乎表明情况并非如此


    如果ANTS Memory profiler发现一个“主要内存块”被分配给了非托管代码,而您预期没有非托管内存使用,那么这将是一个开始调查的好地方

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

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