[英]C# WebAPI Garbage Collection
我刚刚向第一个客户交付了我的第一个C#WebAPI应用程序。 在正常负载下,性能最初比我预期的还要好。 原来。
一切工作正常,直到内存耗尽并且垃圾收集开始骚乱(如“它收集尚未垃圾的对象”中所述)。 那时,有多个W3WP线程,总共约有10个演出,每个工人个位数演出。 IIS重新启动后,一切恢复正常,但是内存使用率当然又在上升。
如果我错了,请纠正我,但是
并请帮助我:
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.