ASP.NET应用程序的高内存使用率

我们的一些ASP.Net应用程序存在问题。 我们的一些应用程序从一开始就声称拥有大量内存作为其工作集。

在我们的2个webfarm服务器(每个4GB的RAM)上运行多个应用程序。 我们有一个稳定的环境,大约1.2GB的内存空闲。

然后我们添加一个MVC5 + WebApi v2 +entity framework应用程序,立即声称1 + gb作为工作集内存,而实际上只使用大约300mb。 这导致其他应用程序抱怨没有足够的内存。

我们已经尝试设置虚拟内存限制和私有内存限制,但没有任何效果。 如果我们将其设置为大约500mb,应用程序仍然使用或多或少相同数量的内存(超过500)并且似乎不尊重所设置的限制。

作为参考,我用一个空的MVC5项目(VS2013模板)测试了这个,这已经声称300mb的内存,而只使用大约10mb。

将应用程序设置为32位应用程序似乎对减小工作集的大小有一些影响。

有没有办法减少工作集的大小,或对其大小实施硬性限制?

编辑:如果使用Web Api v2和Entity Framework为项目使用大量内存,我的API控制器如下所示:

namespace Foo.Api { public class BarController : ApiController { private FooContext db = new FooContext(); public IQueryable GetBar(string bla) { return db.Bar.Where(f => f.Category.Equals(bla)).OrderBy(f => f.Year); } } 

因为他们看了我能找到的大多数教程(包括来自微软的教程)。 由于LINQ延迟加载,因此在此处using不起作用。 如果我在任何地方都添加了ToList(未经测试),它可以工作,但这会产生任何其他影响吗?

edit2:如果我这样做的话

 namespace Foo.Api { public class BarController : ApiController { public List GetBar(string bla) { using(FooContext db = new FooContext){ return db.Bar.Where(f => f.Category.Equals(bla)).OrderBy(f => f.Year).ToList(); } } } 

ToList()是否对api的性能有任何影响? (我知道我不能像IQueryable一样便宜地继续查询)

Edit3:我注意到它的应用程序的私有工作集非常高。 有没有办法限制这个? (不会导致不断循环)

编辑4:据我所知,我在每个APIController上都有一个Dispose。 我的前端只是一些简单的MVC控制器,但对于大部分.cshtml和javascript(角度)文件。

我们有另一个应用程序,只是常规的mvc,有两个模型和一些简单的视图(没有数据库,或其他可能被泄露的外部资源),这也消耗了多达4-500mb的内存。 如果我对它进行分析,我看不到任何指示内存泄漏的内容,我确实看到实际上只使用了10或20 mb,其余的是未分配的非托管内存(但是私有内存工作集的一部分,因此声称这个应用程序,任何其他人无法使用)。

我的一些应用程序遇到了类似的问题。 我能够通过将一次性数据库资源包装在using子句中来正确关闭它来解决问题。

对于Entity Framework,这意味着确保在每次请求后始终关闭上下文。 应在请求之间处理连接。

 using (var db = new MyEFContext()) { // Execute queries here var query = from u as db.User where u.UserId = 1234 select u.Name; // Execute the query. return query.ToList(); // This bracket will dispose the context properly. } 

您可能需要将上下文包装到请求缓存上下文的服务中,以便在整个请求期间使其保持活动状态,并在完成时将其处理掉。

或者,如果在MSDN示例中使用具有单个上下文的模式,请确保覆盖Dispose(bool)方法,如此处的示例。

 protected override void Dispose(bool disposing) { if (disposing) { db.Dispose(); } base.Dispose(disposing); } 

所以你的控制器(从上面)应该是这样的:

 namespace Foo.Api { public class BarController : ApiController { private FooContext db = new FooContext(); public IQueryable GetBar(string bla) { return db.Bar.Where(f => f.Category.Equals(bla)).OrderBy(f => f.Year); } // WebApi 2 will call this automatically after each // request. You need this to ensure your context is disposed // and the memory it is using is freed when your app does garbage // collection. protected override void Dispose(bool disposing) { if (disposing) { db.Dispose(); } base.Dispose(disposing); } } } 

我看到的行为是应用程序将消耗大量内存,但它可以垃圾收集足够的内存,以防止它获得OutOfMemoryException 。 这使得很难找到问题,但是处理数据库资源解决了这个问题。 其中一个应用程序用于徘徊在大约600 MB的RAM使用量,现在它徘徊在75 MB左右。

但是这个建议不仅适用于数据库连接。 如果遇到内存泄漏, 任何实现IDisposable类都应该是可疑的。 但既然你提到你正在使用EntityFramework,那么它最可能是嫌疑人。

删除所有Telerik Kendo MVC引用(DLL等)修复了我们的问题。 如果我们没有运行应用程序,我们所有的内存问题都消失了,我们看到正常的内存使用。

基本上:它是一个导致高内存使用的外部库。