c# - 尽管可用内存充足,但使用 Report.Render() 方法时出现 OutOfMemoryException
问题描述
当调用 Report.Render() 方法 ( https://docs.microsoft.com/en-us/dotnet/api/microsoft.reporting.webforms.report.render )时,我们公司的客户遇到周期性的 OutOfMemoryException 。尽管所有迹象都表明操作系统在故障点有足够的可用内存,但仍会发生这种情况。在这种情况下,报告会被提供一个包含嵌入图像的 RDLC 文件。RDLC 文件的大小为 321KB。
我们为相关进程添加了一些内存诊断:
- 紧接在 Render() 方法调用之前,工作进程显示有大约 412MB 的内存占用,尽管这个数量自然会有所不同。从未见过高于 600MB 的文件。(这是使用GC.GetTotalMemory(false)确定的。)
- 在 Render() 方法调用之前,操作系统会报告系统上的以下内存可用性(使用 GlobalMemoryStatusEx 函数(https://docs.microsoft.com/en-us/windows/win32/api/ sysinfoapi/nf-sysinfoapi-globalmemorystatusex )):
Memory in use....................: 28%
Total physical memory............: 8191MB
Available physical memory........: 5880MB
Total paging file................: 28671MB
Available paging file............: 26318MB
Total virtual memory.............: 4095MB
Available virtual memory.........: 4007MB
Available extended virtual memory: 0MB
这是堆栈跟踪的一部分;请注意,确切的故障点有时会有所不同,报告的确切异常也是如此。但到目前为止,最常见的异常是 OutOfMemoryException:
Microsoft.Reporting.WebForms.LocalProcessingException: An error occurred during local report processing. ---> Microsoft.ReportingServices.ReportProcessing.ReportProcessingException: An unexpected error occurred in Report Processing. ---> System.OutOfMemoryException: Out of memory.
at System.Drawing.Image.FromStream(Stream stream, Boolean useEmbeddedColorManagement, Boolean validateImageData)
at Microsoft.ReportingServices.Rendering.ImageRenderer.SharedRenderer.GetImage(RPLReport rplReport, Byte[]& imageData, Int64 imageDataOffset, GDIImageProps& gdiImageProps)
at Microsoft.ReportingServices.Rendering.ImageRenderer.PDFWriter.GetImage(String imageName, Byte[] imageData, Int64 imageDataOffset, GDIImageProps gdiImageProps)
at Microsoft.ReportingServices.Rendering.ImageRenderer.PDFWriter.DrawImage(RectangleF position, RPLImage image, RPLImageProps instanceProperties, RPLImagePropsDef definitionProperties)
at Microsoft.ReportingServices.Rendering.ImageRenderer.Renderer.ProcessImage(RPLMeasurement measurement, RectangleF position)
at Microsoft.ReportingServices.Rendering.ImageRenderer.Renderer.ProcessReportItem(RPLMeasurement measurement, RectangleF bounds, Boolean renderBorders, Boolean hasTablixCellParent)
at Microsoft.ReportingServices.Rendering.ImageRenderer.Renderer.ProcessNonTablixContainerReportItems(RPLContainer container, RectangleF bounds)
at Microsoft.ReportingServices.Rendering.ImageRenderer.Renderer.ProcessReportItem(RPLMeasurement measurement, RectangleF bounds, Boolean renderBorders, Boolean hasTablixCellParent)
at Microsoft.ReportingServices.Rendering.ImageRenderer.Renderer.ProcessPage(RPLReport rplReport, Int32 pageNumber, FontCache sharedFontCache, List`1 paragraphsItemizedData)
at Microsoft.ReportingServices.Rendering.ImageRenderer.PDFRenderer.Render(Report report, NameValueCollection deviceInfo, Hashtable renderProperties, CreateAndRegisterStream createAndRegisterStream)
at Microsoft.ReportingServices.Rendering.ImageRenderer.RendererBase.Render(Report report, NameValueCollection reportServerParameters, NameValueCollection deviceInfo, NameValueCollection clientCapabilities, Hashtable& renderProperties, CreateAndRegisterStream createAndRegisterStream)
at Microsoft.ReportingServices.ReportProcessing.ReportProcessing.RenderReport(IRenderingExtension newRenderer, DateTime executionTimeStamp, ProcessingContext pc, RenderingContext rc, IChunkFactory cacheDataChunkFactory, IChunkFactory yukonCompiledDefinition, Boolean& dataCached)
运行此 Web 应用程序的此应用程序池配置有专用内存限制、请求限制和虚拟内存限制值均设置为 0(无限制)。
在我们的代码中,在调用 Render() 方法之后,我们还调用以下内容来尝试释放报告生成所占用的内存:
report.DataSources.Clear();
report.ReleaseSandboxAppDomain();
report.Dispose();
我欢迎任何关于这个问题的想法或建议。
解决方案
推荐阅读
- python-3.x - 二维数组的sklearn线性回归
- python - 从 pandas 数据框中获取随机样本,但每个值只有一个
- android - 即使应用程序“中断”,SetRepeating() 方法 Android [Xamarin.Forms] 中的动态间隔
- javascript - 将数组设置为 null 然后在 useEffect React 中更新它
- python - 使用 virtualenv 时如何指定我的机器上未安装的 python 版本?
- sass - 如何使用未定义数量的参数来匹配映射中的键并将它们添加为属性?
- android - 使用我的计时器在 ViewModel 中获取数据(在 kotlin 中)
- flutter - 使用 Flutter 在可点击的图像上显示文本
- android - Stack Navigator:从 React Native Screen 导航到 Native Screen,然后跳回 React Native Screen?
- mysql - 如何在我的表中获取 ID 为最大 ID 的特定字段?