C#的WebAPI垃圾收集(C# WebAPI Garbage Collection)

2019-10-20 06:35发布

我只是发表我的第一个C#的WebAPI应用程序的第一个客户。 在正常负荷下,最初的表现甚至比我预期的要好。 原来。

一切运行良好,直到,在某些时候,内存上涨和垃圾收集开始运行骚乱(如“它收集尚未成为垃圾对象”)。 在这一点上,有多个线程W3WP的RAM十几个演出干脆,和每个工人的个位数的演出。 IIS的一切重启后恢复正常,但当然,内存使用量再度上升。

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

  • 应该不是C#有自动垃圾收集?
  • 它不应该是容易的GC收集的WebAPI应用程序的垃圾?

并请帮我出:

  • 我怎样才能明确说明GC应该收集哪些,从而避免了内存泄露? 是someBigList = null; 要走的路?
  • 我怎么可以检测内存泄漏是谁?

编辑:让我澄清一些事情。

我的.NET应用程序的WebAPI大多是一帮

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();
    }
}

在这种条件下,GC应该很容易:“回归”后,所有局部变量应该是垃圾。 然而,随着每一个呼叫使用内存增加。

我最初以为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扔了一个空指针错误,这在我看来只能通过GC造成的,因为我没有找到任何地方的代码someVar正在积极通过我无效。

我认为内存增速放缓,因为我积极最常用的控制器以空集最大的数组变量,但这只是一个直觉,甚至几乎没有一个完整的解决方案。

我现在将使用您提供的链接做了一些分析,并取回了一些成果。

Answer 1:

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

C#是一种编程语言,用于.NET运行库和.NET带来的自动垃圾收集表。 所以,是的,虽然在技术上C#是不是带来了它的一块。

它不应该是容易的GC收集的WebAPI应用程序的垃圾?

当然,这应该只是作为任何其他类型的.NET应用程序一样简单。

这里的共同主题是垃圾 。 如何确定.NET的东西是垃圾? 通过验证,有对象没有更多的活动引用。 说实话,我认为这是更有可能的是,你已经验证自己的假设错误之一,相比于存在于这样的垃圾收集器一个严重的错误,“它收集那些尚未垃圾对象”。

为了找到泄漏,你需要弄清楚哪些对象当前保存在内存中,使确定这是否是正确与否,如果没有,弄清楚什么是阻碍他们那里。 内存分析器应用,将有助于这一说法,有许多可用的,如红门蚂蚁内存分析器 。

为了您的其他问题,如何使一些符合垃圾回收? 通过把它变成垃圾(见上面的定义)。 请注意,设置一个局部变量来null未必帮助或需要。 设置一个静态变量null ,但是, 可能会 。 但要确定正确的方法是使用一个分析器。

这里有一些镜头,在这黑暗的类型提示,你可能会考虑的:

  • 看看静态类,静态字段和静态特性。 你存储数据那里,正在积累?
  • 如何静态事件? 你有这个吗? 你还记得退订事件,当你不再需要它吗?
  • 并通过“静态字段,属性和事件”,我还指在直接或间接地存储在静态字段或属性的对象持有正常的实例字段,属性和事件。 基本上,任何将保留对象在内存中。
  • 你要记住Dispose所有的IDisposable对象? 如果没有,那么所使用的内存可能是不受管理。 但是,通常,当垃圾收集器收集的管理对象,该对象的终结应清理非托管内存为好,但你可能会分配内存的GC算法是不知道的,因此认为它不是一个大问题等与收集。 见GC.AddMemoryPressure更多关于此方法。


文章来源: C# WebAPI Garbage Collection