随着时间的推移,SQL 存储过程会消耗内存
我一直在尝试诊断此 Web 服务中的 30 MB 内存泄漏。它使用标准存储过程从 SQL 中进行一些批量获取。每个“批量”返回大约 10,000-50,000 行。 Web 服务生成报告并将其发送给调用者。
似乎每次您调用此报告时,30 MB 的内存都会被“吃掉”并且不会被释放。因此,如果您调用同一个调用大约 1,000 次,3 GB 系统就会耗尽内存。如果您回收应用程序池,则会释放内存。你可以在那里坐一天,内存也不会被释放。因此,随着时间的推移,网络服务器会耗尽内存。
我单步调试了代码,对其进行了分析,最终确定是这 3 个“批量”获取获取了适量的数据。每个人都会取出 10 MB,并且在完成后不会归还。存储过程很好。有关调用的唯一奇怪的事情是,它使用 LINQ 来调用存储过程,并使用 XML 映射文件将数据转换为 Poco 对象。
我尝试更改它,以便每次调用存储过程时都使用新的 DataContext,然后将 DataContext 设置为 null。我尝试将所有类型的对象设置为 null,然后调用 GC.Collect,但内存仍然被占用并且不会释放,直到您回收应用程序池。
我将不胜感激任何线索。我怀疑这与 LINQ 和大数据返回有关。
I've been trying to diagnosis this 30 MB memory leak in this webservice. It has some bulk gets from SQL using standard stored procs. Each "bulk" returns around 10,000-50,000 rows. The webservice generates its report and sends it to the caller.
It seems everytime you call for this report 30 MB of memory gets "eaten" and not released. So if you hit the same call about 1,000 times the 3 GB system runs out of memory. If you recycle the app pool the mem is released. You can sit there for a day and the mem will not be released. So overtime the webserver runs out of memory.
I steped through the code, anaylysised hte heck out of it, and finally determined it was these 3 "bulk" gets that get a moderate amount of data. Each takes out 10 MB and doesn't give it back after they're done. The stored procs are fine. The only odd thing about the calls is that it uses LINQ to call the stored procs and translate the data into Poco objects, using an XML map file.
I tried changing it so they use a new DataContext every single time the stored proc is called and then set the DataContext to null. I tried setting all sort of objects to null and then calling GC.Collect and the mem is still being eaten and not released until you recycle the app pool.
I would appreciate any leads. I suspect this has something to do with LINQ and large data returns.
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(1)
这就是垃圾收集的丑陋的一面:开发人员倾向于认为他们不再需要担心释放内存。但这并不完全正确!
某些类实例必须进行 Dispose(如 .Net 中的称呼)。事实上,每个实现 IDisposable 的对象都必须由开发人员处理其内存周期。
流就是一个很好的例子。流是一次性的,并且它们通常携带大量数据(大于简单字符串)。想象一个服务,每 5 秒处理一个 2KB 的流。这不太对吧?比如说,它是一个小的 XML。但如果您不处理它会发生什么?好吧,当然,您可以自己计算一下,但我会给您结果:约 33.7 MB 的未使用垃圾。
底线:处理掉你的一次性用品。
That's the ugly side of having garbage collection: developers tend to think they do not need worry about freeing memory anymore. But that's not entirely true!
Some class instances have to be Disposed (as it's called in .Net). In fact, every object that implements
IDisposable
has to have its memory cycle handled by the developer.Streams are a good example. Streams are disposable AND they usually carry a larger amount of data (larger than a simple string). Imagine a service where every 5 seconds you handle a 2KB stream. That's not much right? It's, say, a small XML. But what happens if you do not dispose it? Well, you can do the math yourself, of course, but I'll give you the result: ~33.7 MB of unused junk.
Bottom line: get disposed of your disposables.