在ASP.NET MVC网站的web服务器上使用6gb RAM的IIS工作进程
我有一个网站在它自己的应用程序池(IIS 8)中运行。池的设置为默认设置,即每29小时循环一次 我们的web服务器只有8gbram,我注意到这个网站的工作进程经常攀升到6gbram,并使服务器的运行速度减慢到爬行状态。这是web服务器上当前唯一的站点 我还安装了SQL Express 2016。该站点使用的是EF版本6.1.3 MVC站点非常简单。它有一个GETPDF控制器,可以在表中查找一行,获取存储在字段中的PDF信息,然后将其返回浏览器,如下所示:-在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
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子句再次获取数据
直到数据库开始填满,我才注意到这个问题
我是雷莫