首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >在具有ASP.NET MVC网站的web服务器上使用6 6gb内存的IIS工作进程

在具有ASP.NET MVC网站的web服务器上使用6 6gb内存的IIS工作进程
EN

Stack Overflow用户
提问于 2017-06-26 23:09:01
回答 2查看 452关注 0票数 1

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

我们的web服务器只有8 8gb的RAM,我注意到这个网站的工作进程经常会攀升到6 8gb的RAM,并使服务器变得缓慢。这是web服务器上当前唯一的站点。

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

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

代码语言:javascript
复制
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");

}

这里有没有内存泄漏?

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

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

如果代码看起来没问题,那么从哪里开始查找比较好呢?

问候

EN

回答 2

Stack Overflow用户

发布于 2017-06-26 23:28:53

这里有没有内存泄漏?

不是的。

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

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

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

不是的。

如果代码看起来不错,那么从哪里开始查找会是一个好的开始呢?

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

没有必要这样做。

要消除文件的第二个副本,请使用MemoryStream(byte[])构造函数,而不是将字节从byte[]复制到空MemoryStream。

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

请参阅https://docs.microsoft.com/en-us/dotnet/framework/data/adonet/sqlclient-streaming-support

如果您转到ADO.NET streaming您的DbContext,将需要将作用域限定为您的控制器,而不是局部变量,这在任何情况下都是一个很好的实践。

票数 0
EN

Stack Overflow用户

发布于 2017-06-27 01:26:24

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

代码语言:javascript
复制
**db.eBillDatas.ToList<eBillData>()**

因此,我从数据库获取所有数据,然后使用where子句再次获取数据。

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

我删除了这一部分,现在IIS工作进程大约是100mb。

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/44762835

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档