我有一个在自己的应用程序池(IIS 8)中运行的网站。池的设置为默认设置,即每29小时回收一次。
我们的web服务器只有8 8gb的RAM,我注意到这个网站的工作进程经常会攀升到6 8gb的RAM,并使服务器变得缓慢。这是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");
}这里有没有内存泄漏?
文件字节数组和内存流是否会被释放?
另外,关于清除实体框架引用,我还需要做什么吗?
如果代码看起来没问题,那么从哪里开始查找比较好呢?
问候
发布于 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,将需要将作用域限定为您的控制器,而不是局部变量,这在任何情况下都是一个很好的实践。
发布于 2017-06-27 01:26:24
除了大卫的建议之外。我注意到我正在执行以下操作
**db.eBillDatas.ToList<eBillData>()**因此,我从数据库获取所有数据,然后使用where子句再次获取数据。
直到数据库开始填满,我才注意到这个问题。
我删除了这一部分,现在IIS工作进程大约是100mb。
https://stackoverflow.com/questions/44762835
复制相似问题