【问题标题】:From time to time we have System.OutOfMemoryException error on our asp.net web application我们的 asp.net Web 应用程序有时会出现 System.OutOfMemoryException 错误
【发布时间】:2015-08-01 05:40:44
【问题描述】:

有时,我们的 Web 应用程序会导致此错误:

System.OutOfMemoryException: Exception of type 'System.OutOfMemoryException' was thrown.

该应用程序是 C# ASP.NET 4.5 Web Forms 应用程序,运行在具有 6G 内存的 Windows 2008 R2 服务器上。我们已经增加了几次内存,但它仍然会发生。所以我想知道它的应用程序是否有问题?可能是什么原因?

编辑

我有这个堆栈,不知道它是否有帮助:

System.OutOfMemoryException: Exception of type 'System.OutOfMemoryException' was thrown.

Generated: Wed, 29 Jul 2015 08:49:24 GMT

System.OutOfMemoryException: Exception of type 'System.OutOfMemoryException' was thrown.
   at ASP.popups_downloadtrendpdf_aspx.__BuildControlTree(popups_downloadtrendpdf_aspx __ctrl)
   at ASP.popups_downloadtrendpdf_aspx.FrameworkInitialize()
   at System.Web.UI.Page.ProcessRequest(Boolean includeStagesBeforeAsyncPoint, Boolean includeStagesAfterAsyncPoint)
   at System.Web.UI.Page.ProcessRequest()
   at System.Web.UI.Page.ProcessRequestWithNoAssert(HttpContext context)
   at System.Web.UI.Page.ProcessRequest(HttpContext context)
   at ASP.popups_downloadtrendpdf_aspx.ProcessRequest(HttpContext context)
   at System.Web.HttpApplication.CallHandlerExecutionStep.System.Web.HttpApplication.IExecutionStep.Execute()
   at System.Web.HttpApplication.ExecuteStep(IExecutionStep step, Boolean& completedSynchronously)

编辑

这是生成 PDF 的代码,它基于 XSL-FO 字符串。这会导致问题吗?

PDFGenerator.PDFGenerator svc = new PDFGenerator.PDFGenerator();
byte[] myfile = svc.ProcessFO(foString);
if (myfile != null)
{
    System.Web.HttpResponse response = System.Web.HttpContext.Current.Response;
    response.Clear();
    response.AddHeader("Content-Type", "application/pdf");
    response.AddHeader("Content-Disposition", "attachment; filename=" + filename + "; size=" + myfile.Length.ToString());
    response.Flush();
    response.BinaryWrite(myfile);
    response.Flush();                    
 }

编辑

ProcessFO() 的代码:

    [WebMethod]
    public byte[] ProcessFO(string requestFO)
    {
        byte[] result = null;
        FODocument doc = new FODocument();
        try
        {
            byte[] byteArray = System.Text.Encoding.UTF8.GetBytes(requestFO);
            using (MemoryStream stream = new MemoryStream(byteArray))
            {
                using (MemoryStream pdfStream = new MemoryStream())
                {
                    doc.generate(stream, pdfStream);
                    result = pdfStream.ToArray();
                }
            }
        }
        catch (System.Exception exc)
        {
            logger.Debug("Trouble in ProcessFO: " + exc.Message);
            logger.Debug(exc.StackTrace);
        }
        return result;
    }

【问题讨论】:

  • 内存不足的原因有很多,通常不是因为总内存。您能否发布导致问题的代码?没有它,我们真的无法给出一个好的答案。
  • 这可能是由于代码问题,但也可能与服务器上发生的其他事情有关;服务器与许多组件共享内存,而其他东西可能会很麻烦。
  • 听起来很正常的内存泄漏(对象不断在内存中累积)。在测试服务器上做一些内存分析。搜索诸如 .net 内存分析内存泄漏之类的术语如何
  • 我们可以获得完整的堆栈跟踪吗?也许是一些代码处理文件上传,有人上传了一个 +inf 字节的大文件?您是否检查过性能监视器以查看不同 gc 代的大小?

标签: c# asp.net out-of-memory


【解决方案1】:

这看起来像你有内存泄漏。现在我不会进入虚拟内存与物理内存,但这里的解决方案不是增加内存。您必须修复代码中“泄漏”的部分。

在 .net 中,可能有很多可能性(未发布事件处理程序(在桌面应用程序中可能更多)、非托管内存的处置等),所以没有代码,这个答案无法深入了解详情。

您应该尝试一些内存分析器(开始试用 dotMemory 或 redgate 的内存分析器)。或者,使用 sos 库查找 WinDbg。

【讨论】:

    【解决方案2】:

    查看堆栈跟踪我看到“downloadtrendpdf”。应用程序是否在内存中缓冲 PDF 文件以进行上传/下载操作?许多 WebForms 控件因这样做而臭名昭著。这会让你很快耗尽内存。

    【讨论】:

    • 这就是问题所在。大字节数组会占用大量内存。尝试查看svc 对象上是否有任何方法返回Stream 而不是byte[]
    • 我有两个问题,目前的方法会导致内存泄漏吗?另外,为什么流会解决 byte[] 导致的问题? svc.ProcessFO 是我们自己创建的方法,如果需要,我们可以更改它。我在编辑中发布了代码。你认为它会通过返回一个流来解决问题吗?
    • 文件正在发送到HttpContext.Current.Response.OutputStream 流。流将允许您一次将 4 KB 左右的小缓冲区推送到输出流中,而不是将整个文件加载到内存中。确保使用二进制流编写器,而不是基于数组的 MemoryStream 抽象。
    • 这里是一个例子。 fs 变量是文件的 FileStreamstackoverflow.com/questions/5828315/… 在 4.5 .NET 版本中,流也有一个 CopyTo 方法,它是一个使用 4KB 缓冲区的循环。所以代码是fs.CopyTo(Response.OutputStream)
    猜你喜欢
    • 2023-03-08
    • 2019-06-09
    • 1970-01-01
    • 2014-02-07
    • 2016-08-16
    • 2019-06-08
    • 1970-01-01
    • 2020-09-07
    • 1970-01-01
    相关资源
    最近更新 更多