C#的WebAPI垃圾收集 [英] C# WebAPI Garbage Collection

查看:207
本文介绍了C#的WebAPI垃圾收集的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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

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

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


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

  • 难道不应该是容易的GC收集的WebAPI应用?
  • 的垃圾

和请帮我:


  • 如何明确说明应该收集哪些GC,从而$ ​​P $ pventing内存泄漏?为 someBigList = NULL; 的路要走

  • 如何检测,其中内存泄漏?

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

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

 公共类MyApiController:ApiController
{
    [HTTPGET]
    公共MyObjectClass [] MyApi(字符串someParam){
        清单< MyObjectClass>名单=新名单,LT; MyObjectClass>();
        ...
        为/,而/的foreach {
            MyObjectClass的obj =新MyObjectClass();
            obj.firstStringAttribute = XYZ;
            ...
            list.Add(OBJ);
        }
        返回list.ToArray();
    }
}

在这种情况下,气相色谱应该很容易:回归之后,所有的局部变量应垃圾。然而,随着每一个呼叫使用的内存增加。

我最初以为C#的WebAPI程序的行为类似(pre-编译)PHP:IIS调用程序时,它被执行,返回值,然后完全丢弃掉

但是,这并非如此。例如,我发现静态变量来运行之间他们的数据,现在我都处理静态变量的。

由于我发现静态变量是对GC的一个问题:

 内部类助手
 {
     私人静态列表<串GT; someVar =新的List<串GT;();
     内部助手(){
         someVar =新的List<串GT;();
     }
     内部空隙someFunc(字符串str){
         someVar.Add(STR);
     }
     内部的String [] someOtherFunc(字符串str){
         字符串[] S = someVar.ToArray();
         someVar =新的List<串GT;();
         返回S;
     }
 }

下面,低内存情况下,someVar扔了一个空指针错误,这在我看来只能通过GC造成的,因为我没有找到任何code其中 someVar 正在积极由我废止。

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

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


解决方案

  

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


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


  

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


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

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

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

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

下面是一些射中这黑暗的技巧型的,你可能会考虑:


  • 看静态类,静态字段和静态属性。你存储数据那里,正在积累?

  • 如何静态事件?你有这个吗?你还记得退订事件,当你不再需要它吗?

  • 并以静态字段,属性和事件,我还指在直接或间接地存储在静态字段或属性的对象持有正常实例字段,属性和事件。基本上,任何将保留对象在内存中。

  • 您是否记得为所有的的IDisposable 对象的Dispose ?如果没有,那么所使用的内存可能是不受管理。通常情况下,然而,当垃圾收集器收集管理对象,该对象的终结应清理非托管内存为好,但你可能会分配内存的GC算法是不知道的,因而认为这是一个不大问题等与收藏。请参阅 GC更多关于此.AddMemory pressure 方法。

I just delivered my first C# WebAPI application to the first customer. Under normal load, performance initially is even better than I expected. Initially.

Everything worked fine until, at some point, memory was up and garbage collection started running riot (as in "It collects objects that are not yet garbage"). At that point, there were multiple W3WP threads with some ten gigs of ram altogether, and single-digit gigs per worker. After a restart of the IIS everything was back to normal, but of course the memory usage is rising again.

Please correct me if I am wrong, but

  • Shouldn't C# have automatic garbage collection?
  • Shouldn't it be easy for GC to collect the garbage of a WebAPI application?

And please help me out:

  • How can I explicitly state what GC should collect, thus preventing memory leaks? Is someBigList = null; the way to go?
  • How can I detect where the memory leaks are?

EDIT: Let me clarify some things.

My .NET WebAPI application is mostly a bunch of

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

Under such conditions, GC should be easy: after "return", all local variables should be garbage. Yet with every single call the used memory increases.

I initially thought that C# WebAPI programs behave similar to (pre-compiled) PHP: IIS calls the program, it is executed, returns the value and is then completely disposed off.

But this is not the case. For instance, I found static variables to keep their data between runs, and now I disposed of all static variables.

Because I found static variables to be a problem for 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;
     }
 }

Here, under low-memory conditions, someVar threw a null pointer error, which in my opinion can only be caused by GC, since I did not find any code where someVar is actively nullified by me.

I think the memory increase slowed down since I actively set the biggest array variables in the most often used Controllers to null, but this is only a gut feeling and not even nearly a complete solution.

I will now do some profiling using the link you provided, and get back with some results.

解决方案

Shouldn't C# have automatic garbage collection?

C# is a programming language for the .NET runtime, and .NET brings the automatic garbage collection to the table. So, yes, although technically C# isn't the piece that brings it.

Shouldn't it be easy for GC to collect the garbage of a WebAPI application?

Sure, it should be just as easy as for any other type of .NET application.

The common theme here is garbage. How does .NET determine that something is garbage? By verifying that there are no more live references to the object. To be honest I think it is far more likely that you have verified one of your assumptions wrongly, compared to there being a serious bug in the garbage collector in such a way that "It collects objects that are not yet garbage".

To find leaks, you need to figure out what objects are currently held in memory, make a determination whether that is correct or not, and if not, figure out what is holding them there. A memory profiler application would help with that, there are numerous available, such as the Red-Gate ANTS Memory Profiler.

For your other questions, how to make something eligible for garbage collection? By turning it into garbage (see definition above). Note that setting a local variable to null may not necessarily help or be needed. Setting a static variable to null, however, might. But the correct way to determine that is to use a profiler.

Here are some shot-in-the-dark type of tips you might look into:

  • Look at static classes, static fields, and static properties. Are you storing data there that is accumulating?
  • How about static events? Do you have this? Do you remember to unsubscribe the event when you no longer need it?
  • And by "static fields, properties, and events", I also mean normal instance fields, properties and events that are held in objects that directly or indirectly are stored in static fields or properties. Basically, anything that will keep the objects in memory.
  • Are you remembering to Dispose of all your IDisposable objects? If not, then the memory being used could be unmanaged. Typically, however, when the garbage collector collects the managed object, the finalizer of that object should clean up the unmanaged memory as well, however you might allocate memory that the GC algorithm isn't aware of, and thus thinks it isn't a big problem to wait with collection. See the GC.AddMemoryPressure method for more on this.

这篇关于C#的WebAPI垃圾收集的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆