.NET 4 WCF内存问题 [英] .NET 4 WCF memory issue

查看:224
本文介绍了.NET 4 WCF内存问题的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我遇到的问题是,在负载测试期间,我的 ASP.NET 4 MVC 2 + WCF 应用程序会在 Windows 2008 64位应用程序中使用大量内存,几分钟后运行几乎所有可用内存(8 GB)(我们没有几个工作进程正在运行)。



在使用 ANTS Memory Profiler 进行分析后,它显示出一些有趣的结果:

  • .NET托管内存从15 MB增加到40 MB,但这归因于我们在程序中执行的缓存机制。 然而,.NET本身分配的空间大约为180 MB,这是意想不到的。
  • 运行了大约3分钟(尽管我们的应用程序没有明确使用任何P / Invoke或COM对象,但是我们确实使用了一些在finally块中使用的COM +对象)。 $ b
  • 内存变成碎片。

  • 商品编号1& 2以上导致整个应用程序在负载测试运行几分钟后使用大约350 MB ,但如果我们没有停止测试,它将继续增长。

  • 根据上面的第1项,我测试了一些应用程序以测试问题是由于我们的应用程序还是WCF造成的。 测试应用程序只是将XML数据(大约300KB)加载到多线程应用程序中的数据集中。当逻辑存储在EXE程序中时,应用程序在完成后仅使用200 KB(从未使用的内存以40 KB开始的额外的120 KB)从24 MB私有字节管理的内存(这是可接受的); 但是当逻辑托管在WCF中时,应用程序使用66 MB托管内存(从64 MB空闲/未使用的托管内存开始,额外为61 MB)。所以看起来WCF / ASP.NET是导致内存增加的原因之一)。


    1. 为什么.NET会在堆中分配如此多的可用空间?了解可用空间可能是在内存快照过程中GC编辑的某些Gen 0 / Gen 1 / Gen 2,但我不认为应用程序真的用尽了那么多的内存。

    2. 是WCF的正常行为吗?如果是的话,任何方式来改变行为,以便它使用较少的内存?

    3. $ b
      $ b p>在此先感谢,



      Willy

      解决方案

      缓冲区来处理消息。你认为内存泄漏可能是尚未收集的临时缓冲区。

      为了避免WCF使用 BufferManager 重复使用缓冲区,直至 maxBufferPoolSize (link to the element here ),默认为512KB。任何超出此限制的请求都会导致创建新的缓冲区,这些缓冲区将不会被重用,并且必须进行垃圾回收。



      另一个选项是maxBufferSize,它限制最大缓冲区大小可以由BufferManager返回。较大的缓冲区不汇集,必须进行垃圾收集。如果您使用大消息,则可以通过增加此属性来减少临时缓冲区。



      尝试增加 maxBufferPoolSize 查看是否可以减少内存使用量。我强烈建议尽管不要最大化它,因为池中的缓冲区在应用程序域(即应用程序池)回收之前不会释放。一段时间的高流量可能会导致大量内存被使用,从未释放。


      I hit issue that my ASP.NET 4 MVC 2 + WCF application utilize lots of memory in Windows 2008 64-bit application during the load testing where it will use up almost all the available memory (8 GB) after few minutes run (we did have few worker process running).

      After profiling using ANTS Memory Profiler it was showing few interesting outcome:

      1. .NET managed memory increase from 15 MB to 40 MB, However this is attributed to caching mechanism that we did in the program. However .NET itself allocate allocate almost 180 MB Free Space, which is unexpected.
      2. Unmanaged Memory size increases significantly until 120 MB after the load test just running about 3 minutes (although our application didn't explicitly use any P/Invoke or COM object. However we did use a few COM+ object which is disposed after used in the finally block).
      3. Memory become fragmented.
      4. Both item no 1 & 2 above causing the whole application to use about 350 MB just after the load test running a few minutes but if we didn't stop the test it will continue to grow further.

      Based on item no 1 above, I tested some application to test whether the issue is due to our application or WCF. The test application just load XML data (about 300KB) to dataset in a multithreading application. When the logic is stored in EXE program, the application use only 200 KB (additional 120 KB from beginning with 40 KB for unused memory) managed memory from 24 MB private bytes after finish (which is acceptable); but when the logic is hosted in WCF, the application uses 66 MB managed memory (additional 61 MB from beginning with 64 MB free/unused managed memory). So it seems that WCF / ASP.NET is the one that causing the memory to increase a lot).

      1. Why .NET allocate so much free space in the heap? Understood that the free space could be some Gen 0/Gen 1/Gen 2 that is GC-ed during memory snapshot process, but I don't think the application really use up that much memory.
      2. is the behavior normal for WCF? If yes, any way to change the behavior so that it uses lesser memory?
      3. How to find unmanaged memory leak especially that I didn't use the unmanaged code explicitly?

      Appreciate your advise on the question above.

      Thanks in advance,

      Willy

      解决方案

      WCF uses temporary buffers to process messages. What you perceive as a memory leak may be temporary buffers that haven't been collected yet.

      To avoid creating new buffers all the time WCF uses BufferManager to reuse buffers, up to the limit specified by maxBufferPoolSize(link to the element here), which by default is 512KB. Any requests beyond this limit cause new buffers to be created that are never reused and have to be garbage collected.

      Another option to check is maxBufferSize, which limits the maximum buffer size that can be returned by the BufferManager. Larger buffers are not pooled and have to be garbage collected. If you use large messages, you may be able to reduce the temporary buffers by increasing this property.

      Try increasing maxBufferPoolSize to see if you can reduce memory usage. I would strongly advice though NOT to max it, because buffers from the pool are never released until the app-domain (ie the Application Pool) recycles. A period of high traffic could cause a lot of memory to be used and never released.

      这篇关于.NET 4 WCF内存问题的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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