繁体   English   中英

C#WebAPI垃圾收集

[英]C# WebAPI Garbage Collection

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

一切工作正常,直到内存耗尽并且垃圾收集开始骚乱(如“它收集尚未垃圾的对象”中所述)。 那时,有多个W3WP线程,总共约有10个演出,每个工人个位数演出。 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主动使我无效。

我认为自从我将最常用的Controller中最大的数组变量主动设置为null以来,内存的增长速度变慢了,但这只是一种直觉,甚至不是一个完整的解决方案。

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

C#不应该具有自动垃圾收集功能吗?

C#是.NET运行时的编程语言,.NET将自动垃圾收集带到表中。 因此,是的,尽管从技术上讲C#并不是带来它的部分。

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

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

这里的共同主题是垃圾 .NET如何确定某些东西是垃圾? 通过验证没有更多的对该对象的实时引用。 坦白地说,与垃圾收集器中存在一个严重的错误(即“它收集尚未垃圾的对象”)相比,您错误地验证了一个假设的可能性更大。

要查找泄漏,您需要确定内存中当前保留了哪些对象,确定该对象是否正确,如果不正确,则找出存在哪些对象。 内存分析器应用程序将帮助您解决这一问题,它有很多可用的方法,例如Red-Gate ANTS内存分析器

对于您的其他问题,如何使某些东西符合垃圾收集的条件? 通过将其变成垃圾(请参阅上面的定义)。 注意,将局部变量设置为null可能不一定有帮助或需要。 但是, 可以将静态变量设置为null 但是确定这一点的正确方法是使用探查器。

这是您可能会发现的一些暗中技巧:

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

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM