在ASP.NET MVC网站的web服务器上使用6gb RAM的IIS工作进程

在ASP.NET MVC网站的web服务器上使用6gb RAM的IIS工作进程,asp.net,entity-framework,memory-leaks,Asp.net,Entity Framework,Memory Leaks,我有一个网站在它自己的应用程序池(IIS 8)中运行。池的设置为默认设置,即每29小时循环一次 我们的web服务器只有8gbram,我注意到这个网站的工作进程经常攀升到6gbram,并使服务器的运行速度减慢到爬行状态。这是web服务器上当前唯一的站点 我还安装了SQL Express 2016。该站点使用的是EF版本6.1.3 MVC站点非常简单。它有一个GETPDF控制器,可以在表中查找一行,获取存储在字段中的PDF信息,然后将其返回浏览器,如下所示:- using (eBillingEnti

我有一个网站在它自己的应用程序池(IIS 8)中运行。池的设置为默认设置,即每29小时循环一次

我们的web服务器只有8gbram,我注意到这个网站的工作进程经常攀升到6gbram,并使服务器的运行速度减慢到爬行状态。这是web服务器上当前唯一的站点

我还安装了SQL Express 2016。该站点使用的是EF版本6.1.3

MVC站点非常简单。它有一个GETPDF控制器,可以在表中查找一行,获取存储在字段中的PDF信息,然后将其返回浏览器,如下所示:-

using (eBillingEntities db = new eBillingEntities())
{
try
{
    string id = model.id;
    string emailaddress = Server.HtmlEncode(model.EmailAddress).ToLower().Trim();  

    eBillData ebill = db.eBillDatas.ToList<eBillData>().Where(e => e.PURL == id && e.EmailAddress.ToLower().Trim() == emailaddress).FirstOrDefault<eBillData>();

    if (ebill != null)
    {

        // update the 'Lastdownloaded' field.
        ebill.LastDownloaded = DateTime.Now;
        db.eBillDatas.Attach(ebill);
        var entry = db.Entry(ebill);
        entry.Property(en => en.LastDownloaded).IsModified = true; 
        db.SaveChanges();


        // Find out from the config record whether the bill is stored in the table or in the local pdf folder.
        //
        Config cfg = db.Configs.ToList<Config>().Where(c => c.Account == ebill.Account).FirstOrDefault<Config>();

        bool storePDFDataInEBillTable = true;

        if (cfg != null)
        {
            storePDFDataInEBillTable = cfg.StorePDFDataInEBillDataTable;
        }
        // End of Modification

        byte[] file;

        if (storePDFDataInEBillTable)
        {

            file = ebill.PDFData;
        }
        else
        {

            string pathToFile = "";

            if (string.IsNullOrEmpty(cfg.LocalPDFDataFolder))
                pathToFile = cfg.LocalBackupFolder;
            else
                pathToFile = cfg.LocalPDFDataFolder;

            if (!pathToFile.EndsWith(@"\"))
                pathToFile += @"\";

            pathToFile += ebill.PDFFileName;

            file = System.IO.File.ReadAllBytes(pathToFile);

        }

        MemoryStream output = new MemoryStream();

        output.Write(file, 0, file.Length);
        output.Position = 0;

        HttpContext.Response.AddHeader("content-disposition", "attachment; filename=ebill.pdf");

        return new FileStreamResult(output, "application/pdf");
    }
    else
        return View("PDFNotFound");

}
catch
{
    return View("PDFNotFound");

}
使用(eBillingEntities db=new eBillingEntities())
{
尝试
{
字符串id=model.id;
字符串emailaddress=Server.HtmlEncode(model.emailaddress.ToLower().Trim();
eBillData ebill=db.eBillDatas.ToList()。其中(e=>e.PURL==id&&e.EmailAddress.ToLower().Trim()==EmailAddress)。FirstOrDefault();
如果(ebill!=null)
{
//更新“Lastdownloaded”字段。
ebill.LastDownloaded=DateTime.Now;
db.eBillDatas.Attach(ebill);
var分录=分贝分录(息税前利润);
属性(en=>en.LastDownloaded).IsModified=true;
db.SaveChanges();
//从配置记录中找出账单是存储在表中还是本地pdf文件夹中。
//
Config cfg=db.Configs.ToList(),其中(c=>c.Account==ebill.Account).FirstOrDefault();
bool storePDFDataInEBillTable=true;
如果(cfg!=null)
{
storePDFDataInEBillTable=cfg.storePDFDataInEBillTable;
}
//修改结束
字节[]文件;
if(storePDFDataInEBillTable)
{
file=ebill.PDFData;
}
其他的
{
字符串pathToFile=“”;
if(string.IsNullOrEmpty(cfg.LocalPDFDataFolder))
pathToFile=cfg.LocalBackupFolder;
其他的
pathToFile=cfg.LocalPDFDataFolder;
如果(!pathToFile.EndsWith(@“\”))
路径文件+=@“\”;
pathToFile+=ebill.PDFFileName;
file=System.IO.file.ReadAllBytes(路径文件);
}
MemoryStream输出=新的MemoryStream();
output.Write(file,0,file.Length);
输出位置=0;
HttpContext.Response.AddHeader(“内容处置”、“附件;文件名=ebill.pdf”);
返回新文件streamresult(输出,“application/pdf”);
}
其他的
返回视图(“PDFNotFound”);
}
抓住
{
返回视图(“PDFNotFound”);
}
这里有内存泄漏吗

文件字节数组和内存流是否会被释放

另外,关于清除实体框架引用,我还需要做什么

如果代码看起来不错,那么从哪里开始寻找呢

问候

这里有内存泄漏吗

没有

文件字节数组和内存流是否会被释放

最终,是的。但这可能是你过度使用内存的原因

另外,关于清除实体框架引用,我还需要做什么

没有

如果代码看起来不错,那么从哪里开始寻找呢

如果此代码是导致内存使用率高的原因,那是因为您正在将文件加载到内存中。并且您正在将每个文件的两个副本加载到内存中,一个字节[]中加载一个副本,然后复制到MemoryStream

没有必要那样做

要消除文件的第二个副本,请使用构造函数,而不是将字节[]中的字节复制到空内存流中

要消除内存中的第一个副本,可以将数据流式传输到一个临时文件中,该文件将成为FileStreamResult的目标,或者使用ADO.NET流初始化FileStreamResult

如果转到ADO.NET流媒体,则需要将DbContext的作用域限定到控制器,而不是局部变量,这在任何情况下都是一种很好的做法

这里有内存泄漏吗

没有

文件字节数组和内存流是否会被释放

最终,是的。但这可能是你过度使用内存的原因

另外,关于清除实体框架引用,我还需要做什么

没有

如果代码看起来不错,那么从哪里开始寻找呢

如果此代码是导致内存使用率高的原因,那是因为您正在将文件加载到内存中。并且您正在将每个文件的两个副本加载到内存中,一个字节[]中加载一个副本,然后复制到MemoryStream

没有必要那样做

要消除文件的第二个副本,请使用构造函数,而不是将字节[]中的字节复制到空内存流中

要消除内存中的第一个副本,可以将数据流式传输到一个临时文件中,该文件将成为FileStreamResult的目标,或者使用ADO.NET流初始化FileStreamResult


如果您转到ADO.NET streaming,则需要将DbContext的作用域设置为控制器,而不是局部变量,这在任何情况下都是一种很好的做法。

除了David的建议之外。我注意到我正在执行以下操作

**db.eBillDatas.ToList<eBillData>()**
**db.eBillDatas.ToList()**
因此,我从数据库中获取所有数据,然后使用where子句再次获取数据

直到数据库开始填满,我才注意到这个问题


我删除了该部分,现在IIS工作进程大约为100mb。

除了David的建议之外

**db.eBillDatas.ToList<eBillData>()**
**db.eBillDatas.ToList()**
因此,我从数据库中获取所有数据,然后使用where子句再次获取数据

直到数据库开始填满,我才注意到这个问题

我是雷莫