简体   繁体   English

固定的内存导致C#WebApi中的碎片

[英]Pinned memory causes fragmentation in C# WebApi

We have a web application that works as a reverse proxy (forwarding requests and responses). 我们有一个Web应用程序可以用作反向代理(转发请求和响应)。 This is part of a bigger platform so quite a large number of calls are getting through there. 这是一个更大的平台的一部分,因此有大量的电话通过那里。 The application is run on IIS and we use ASP.NET WebApis ApiController to receive and HttpClient to resend the calls (newer NuGet packages on .NET 4.6.1). 该应用程序在IIS上运行,我们使用ASP.NET WebApis ApiController接收并使用HttpClient重新发送调用(.NET 4.6.1上较新的NuGet程序包)。 We have disabled IIS worker process recycling. 我们已禁用IIS工作进程回收。

In production we can see that over about one week the memory usage is constantly growing and then remaining at a high level. 在生产中,我们可以看到,在大约一周的时间里,内存使用量一直在增长,然后保持较高水平。 Occasionally we are getting OutOfMemoryExceptions. 有时我们会收到OutOfMemoryExceptions。 Using R# dotMemory profiler we couldn't find a memory leak but we can see that there is a huge fragmentation (up to 99%!) of Gen 0 to 2 objects. 使用R#dotMemory事件探查器,我们找不到内存泄漏,但是我们可以看到Gen 0到2对象存在巨大的碎片(高达99%!)。 We assume this is related to the OverlappedData objects that dotMemory marks as pinned. 我们假定这与dotMemory标记为固定的OverlappedData对象有关。

There are some posts out there dealing with this kind of issue, a good one being http://www.ahuwanya.net/blog/post/Buffer-Pooling-for-NET-Socket-Operations - the summary being that the fragmentation is related to the buffer pinning for the IO operations. 有一些关于这种问题的文章,一个很好的是http://www.ahuwanya.net/blog/post/Buffer-Pooling-for-NET-Socket-Operations-摘要是碎片是与IO操作的缓冲区固定有关。 So on this ground we have some questions: 因此,在此基础上,我们有一些问题:

  1. How could we introduce a buffer pool as shown in the post with Sockets for use with ApiController and HttpClient? 我们如何引入一个如Socket所示的缓冲池,以便与ApiController和HttpClient一起使用?
  2. How could we force pinned memory to be released, for example by closing a connection - without having a significant performance loss? 我们如何强制释放固定的内存(例如通过关闭连接)而又不会造成明显的性能损失?
  3. How can we ensure the assumption is correct by getting more detailed information about the pinned memory? 我们如何通过获取有关固定内存的更多详细信息来确保假设正确无误? We found something about logging stacktraces with Perfmon but a more detailed guide would be appreciated. 我们发现了一些有关使用Perfmon记录堆栈跟踪的信息,但更详细的指南将不胜感激。

Of course any other suggestions, hints or remarks that help us to narrow down and solve the issue are appreciated as well. 当然,任何其他有助于我们缩小范围并解决问题的建议,暗示或言论也应受到赞赏。 Please note that we want to solve the issue and not have a workaround for it (such as restarting the IIS worker process every day). 请注意,我们要解决此问题,而没有解决方法(例如每天重新启动IIS工作进程)。

In our current release we don't have this problem anymore. 在当前版本中,我们不再存在此问题。 We have no real explanation for it - the only thing that seems to have changed is that we removed some "volatile" definitions. 我们对此没有真正的解释-似乎唯一改变的是我们删除了一些“易失”定义。 Could this have been the cause? 这可能是原因吗? Maybe yes - in fact we assume it is, but have no real proof for it. 也许是的-实际上我们假设是这样,但没有真正的证据。 According to the documentation it is somewhat unclear whether volatile will prevent memory optimization, but from understanding it is likely. 根据文档,尚不清楚volatile是否会阻止内存优化,但有可能了解这一点。 So we just accept it like this... 所以我们只是这样接受它...

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

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