C# Azure云服务运行Web角色(Web应用程序)内存问题(Gen2)

C# Azure云服务运行Web角色(Web应用程序)内存问题(Gen2),c#,entity-framework,iis,azure,memory,C#,Entity Framework,Iis,Azure,Memory,我有一个关于运行MVC应用程序的Web角色的高内存使用率的问题,简单的注入器作为DI,实体框架6用于DAL。应用程序在Azure云服务上以Web角色运行,具有2个标准A2实例(2个内核,3.5 GB RAM),并且还运行配置了20%内存使用率的CachingService(共址角色) 问题是,当实例启动或重新启动时,w3wp.exe服务的内存使用量仅为500-600 MB左右(所有其他应用的内存使用量约为50%),但即使没有请求进入,它也会启动并继续增长,直到1.7GB左右并停止(所有其他应用的

我有一个关于运行MVC应用程序的Web角色的高内存使用率的问题,简单的注入器作为DI,实体框架6用于DAL。应用程序在Azure云服务上以Web角色运行,具有2个标准A2实例(2个内核,3.5 GB RAM),并且还运行配置了20%内存使用率的CachingService(共址角色)

问题是,当实例启动或重新启动时,w3wp.exe服务的内存使用量仅为500-600 MB左右(所有其他应用的内存使用量约为50%),但即使没有请求进入,它也会启动并继续增长,直到1.7GB左右并停止(所有其他应用的内存使用量约为90%)。但我注意到内存有时会随机下降,当然是在重新启动或重新发布之后

在监控内存堆之后,我注意到是Gen2堆增长并保持较大,在使用ANTS memory Profiler进行本地调试之后,我发现最大数量的Gen2是由类名为“TypeUsage”和“MetadataProperty”的实体框架对象(“System.Data.Entity.Core.Metadata.Edm”命名空间)占用的

现在我的问题是:

  • 这是我们代码中的内存泄漏吗?如果是这样的话,我该如何解决它(我已经检查并尝试处理每个请求创建的DbContext)
  • 这是EF中的内存泄漏吗,如果是这种情况,我可以对此做些什么,也许是另一个DAL框架
  • 这是正常行为吗?我应该保持原样吗

    • 这是EF内存泄漏的可能性很低,这是不正常的,您不应该让它这样。你的代码泄漏内存

      找到漏洞的最佳方法是使用内存分析器(ANTS是一个很好的选择,我使用dotMemory)。探查器将向您显示泄漏的对象,还应向您显示其他两个重要内容:

      • 代码中创建对象的位置的堆栈跟踪
      • 对象树保留对泄漏对象的引用,不允许收集该对象
      这些应该可以帮助您理解对象是如何创建的,以及为什么它们没有被GC’ed

      您提到大部分内存都在Gen2中。这意味着您泄漏的对象被某个“长寿命”引用。这可能是一个静态变量、ASP.Net应用程序或类似的东西

      IIS回收应用程序时,可能会发生内存随机下降。默认情况下,这种情况每29小时发生一次,但IIS的配置可能会有所不同,或者可能决定出于其他目的回收应用程序

      “但我注意到记忆有时会随机下降……”

      可能这不是内存泄漏,而是垃圾收集无法控制的增长问题。几年前我也遇到过类似的情况

      问题是,默认情况下,垃圾收集器允许进程内存增长,直到其大小超过操作系统中完全可用内存的某个界限。当您的进程在云环境(一种共享主机)中运行时,从操作系统的角度来看,它可能仍然没有达到必要的内存限制,因此没有收集内存,但它超出了共享进程的内存限制


      我建议您使用
      GC.collect(0)强制垃圾收集器显式收集内存定期,在一定数量的操作之后。可能它可以解决这个问题。

      我也遇到过类似的问题(带有EF的web应用程序和大量TypeUsage占用转储内存),并发现在应用程序池上设置“启用32位应用程序”大大减少了内存使用

      如果没有看到一些关于EF的代码,很难说。我强烈建议考虑换成Dapper来代替EF。更容易,也没有那么重。=)()建议:尝试了.AsNoTracking()但仍然没有改进,“TypeUsage”和“MetadataProperty”的大小相同您的模型包含多少表/视图,并且您正在使用ObjectContext或CodeFirst?可能相关:是的,它通过ANTS Memory profiler在EF的静态属性中显示对象的位置,但当我处理这些对象时,它们仍然存在,因此它们可能也被其他对象引用,我就是找不到它们。随着我继续研究,我发现内存中的对象是由DbModelBuilder创建的。Build()函数我处理DbContext,但是DbCompiledModel保持不变并且是最大的保留大小。处理对象不会释放它或它所持有的内存(除非它是本机内存)。您可能在某处仍然有对disposed对象的引用,因此GC无法收集它。我可以看到您检查了对象是如何创建的(我回答中的第一个项目符号)。您还应该检查对象的引用树(项目符号#2)。