C#WebAPI垃圾收集

C#WebAPI垃圾收集,c#,memory-leaks,asp.net-web-api,garbage-collection,C#,Memory Leaks,Asp.net Web Api,Garbage Collection,我刚刚向第一位客户交付了我的第一个C#WebAPI应用程序。在正常负载下,最初的性能甚至比我预期的要好。起初 一切正常,直到在某个时候,内存被启动,垃圾收集开始运行(如“它收集尚未成为垃圾的对象”)。在这一点上,有多个W3WP线程,总共有大约10 Gig的ram,每个工作线程有一位数的Gig。重新启动IIS后,一切都恢复正常,但内存使用率当然再次上升 如果我错了,请纠正我,但是 C#不应该有自动垃圾收集吗 GC收集WebAPI应用程序的垃圾不是很容易吗 请帮帮我: 如何明确说明GC应该收集

我刚刚向第一位客户交付了我的第一个C#WebAPI应用程序。在正常负载下,最初的性能甚至比我预期的要好。起初

一切正常,直到在某个时候,内存被启动,垃圾收集开始运行(如“它收集尚未成为垃圾的对象”)。在这一点上,有多个W3WP线程,总共有大约10 Gig的ram,每个工作线程有一位数的Gig。重新启动IIS后,一切都恢复正常,但内存使用率当然再次上升

如果我错了,请纠正我,但是

  • C#不应该有自动垃圾收集吗
  • GC收集WebAPI应用程序的垃圾不是很容易吗
请帮帮我:

  • 如何明确说明GC应该收集什么,从而防止内存泄漏?Is
    someBigList=null要走的路
  • 如何检测内存泄漏的位置
编辑:让我澄清一些事情

我的.NETWebAPI应用程序主要是一堆

public class MyApiController:ApiController
{
    [HttpGet]
    public MyObjectClass[] MyApi(string someParam) {
        List<MyObjectClass> list = new List<MyObjectClass>();
        ...
        for/while/foreach {
            MyObjectClass obj = new MyObjectClass();
            obj.firstStringAttribute = xyz;
            ...
            list.Add(obj);
        }
        return list.ToArray();
    }
}
公共类MyApicController:ApicController
{
[HttpGet]
公共MyObject类[]MyApi(字符串someParam){
列表=新列表();
...
for/while/foreach{
MyObjectClass obj=新的MyObjectClass();
obj.firstStringAttribute=xyz;
...
列表。添加(obj);
}
return list.ToArray();
}
}
在这种情况下,GC应该很容易:在“return”之后,所有局部变量都应该是垃圾。然而,每一次调用所使用的内存都会增加

我最初认为C#WebAPI程序的行为类似于(预编译的)PHP:IIS调用程序,执行它,返回值,然后完全处理掉

但事实并非如此。例如,我发现静态变量在运行之间保留数据,现在我处理了所有静态变量

因为我发现静态变量对GC来说是个问题:

 internal class Helper
 {
     private static List<string> someVar = new List<string>();
     internal Helper() {
         someVar=new List<string>();
     }
     internal void someFunc(string str) {
         someVar.Add(str);
     }
     internal string[] someOtherFunc(string str) {
         string[] s = someVar.ToArray();
         someVar=new List<string>();
         return s;
     }
 }
内部类助手
{
私有静态列表someVar=newlist();
内佣(){
someVar=新列表();
}
内部void someFunc(字符串str){
someVar.Add(str);
}
内部字符串[]someOtherFunc(字符串str){
字符串[]s=someVar.ToArray();
someVar=新列表();
返回s;
}
}
这里,在内存不足的情况下,someVar抛出了一个空指针错误,我认为这只能由GC引起,因为我没有找到任何
someVar
被我主动取消的代码

我认为,由于我主动将最常用的控制器中最大的数组变量设置为null,内存增长速度有所放缓,但这只是直觉,甚至不是一个完整的解决方案

现在,我将使用您提供的链接进行一些分析,并返回一些结果

C#不应该有自动垃圾收集吗

C#是一种用于.NET运行时的编程语言,.NET将自动垃圾收集带到表中。因此,是的,虽然从技术上讲,C#不是带来它的因素

GC收集WebAPI应用程序的垃圾不是很容易吗

当然,它应该和任何其他类型的.NET应用程序一样简单

这里的共同主题是垃圾。NET如何确定某些东西是垃圾?通过验证对象不再有活动引用。老实说,我认为,与垃圾收集器中存在严重的缺陷,即“它收集尚未成为垃圾的对象”相比,您更可能错误地验证了您的一个假设

要查找泄漏,您需要找出内存中当前保存的对象,确定其是否正确,如果不正确,则需要找出保存它们的内容。内存分析器应用程序将有助于实现这一点,有许多可用的内存分析器应用程序,例如

对于您的其他问题,如何使某些内容符合垃圾收集的条件?把它变成垃圾(见上面的定义)。请注意,将局部变量设置为
null
可能不一定有用,也不一定需要。但是,将静态变量设置为
null
,可能会导致错误。但确定这一点的正确方法是使用探查器

下面是一些在黑暗中拍摄的技巧,你可以看看:

  • 查看静态类、静态字段和静态属性。您是否在那里存储正在积累的数据
  • 静态事件怎么样?有这个吗?您是否记得在不再需要时取消订阅该活动
  • 所谓“静态字段、属性和事件”,我还指的是直接或间接存储在静态字段或属性中的对象中的普通实例字段、属性和事件。基本上,任何将对象保留在内存中的东西
  • 您是否记得处置所有您的
    IDisposable
    对象?如果不是,则正在使用的内存可能是非托管的。但是,通常情况下,当垃圾收集器收集托管对象时,该对象的终结器也应该清理非托管内存,但是您可能会分配GC算法不知道的内存,因此认为等待收集不是大问题。有关这方面的更多信息,请参见方法
C#不应该有自动垃圾收集吗

C#是一种用于.NET运行时的编程语言,.NET将自动垃圾收集带到表中。因此,是的,虽然从技术上讲,C#不是带来它的因素

GC收集WebAPI应用程序的垃圾不是很容易吗

当然,它应该和任何其他类型的.NET应用程序一样简单

这里的共同主题是垃圾。NET如何确定某些东西是垃圾?通过验证没有更多的活动r