I'm attaching project where you can see allocations, created by generating and exporting this report.
In archive, you'll also find 2 diagnostic sessions, that you can open in VS, and see that 1 report generation, with Server GC disabled (my initial post was when application was running with Server GC enabled), allocated around 450MB, for report that exported to PDF is 8MB is size. To run example you may need to alter database connection string.
The thing is that we are running Stimulsoft as a report generation server, and at one given moment we can have multiple reports of this, or bigger size generating and exporting, and we are running out of memory, and application crashes.
In Rider, Dynamic Program Analysis Shows multiple allocation issues, regarding exporting to PDF alone:
https://imgur.com/RXU6Tmd
with following stack trace (there is much more):
Code: Select all
at DeflaterEngine..ctor(DeflaterPending)
at Deflater..ctor(int, bool)
at StiExportUtils.MakePdfDeflateStream(byte[])
at StiPdfExportService.RenderPageFooter(double, double)
at StiPdfExportService.ExportPdf1(StiReport, Stream, StiPdfExportSettings)
at StiPdfExportService.ExportPdf(StiReport, Stream, StiPdfExportSettings)
at StiNetCoreReportResponse.ResponseAsPdf(StiReport, StiPdfExportSettings, bool)
at StiNetCoreReportResponse.ResponseAsPdf(StiReport, StiPagesRange, float, float, bool, bool, bool, String, String, StiUserAccessPrivileges, StiPdfEncryptionKeyLength, bool, bool)
at StiNetCoreReportResponse.ResponseAsPdf(StiReport, StiPagesRange, float, float, bool, bool, bool)
at Program+<<<Main>$>g__GenerateReport|0_0>d.MoveNext() in C:\Users\--\Documents\projects\ConsoleApp3\ConsoleApp3\Program.cs:line 29 column 9
at AsyncTaskMethodBuilder+AsyncStateMachineBox<VoidTaskResult,StiDictionary+<SynchronizeAsync>d__105>.ExecutionContextCallback(Object)
at AsyncTaskMethodBuilder+AsyncStateMachineBox<VoidTaskResult,StiDictionary+<SynchronizeAsync>d__105>.MoveNext(Thread)
at AsyncTaskMethodBuilder+AsyncStateMachineBox<VoidTaskResult,StiDictionary+<SynchronizeAsync>d__105>.MoveNext()
at StiReport.RenderAsync()
at AsyncTaskMethodBuilder+AsyncStateMachineBox<VoidTaskResult,StiDictionary+<SynchronizeAsync>d__105>.ExecutionContextCallback(Object)
at AsyncTaskMethodBuilder+AsyncStateMachineBox<VoidTaskResult,StiDictionary+<SynchronizeAsync>d__105>.MoveNext(Thread)
at AsyncTaskMethodBuilder+AsyncStateMachineBox<VoidTaskResult,StiDictionary+<SynchronizeAsync>d__105>.MoveNext()
Code: Select all
at StiPdfExportService.ConvertToEscapeSequence(String)
at StiPdfExportService.RenderText(StiPdfData, Nullable)
at StiPdfExportService.ExportPdf1(StiReport, Stream, StiPdfExportSettings)
at StiPdfExportService.ExportPdf(StiReport, Stream, StiPdfExportSettings)
at StiNetCoreReportResponse.ResponseAsPdf(StiReport, StiPdfExportSettings, bool)
at StiNetCoreReportResponse.ResponseAsPdf(StiReport, StiPagesRange, float, float, bool, bool, bool, String, String, StiUserAccessPrivileges, StiPdfEncryptionKeyLength, bool, bool)
at StiNetCoreReportResponse.ResponseAsPdf(StiReport, StiPagesRange, float, float, bool, bool, bool)
at Program+<<<Main>$>g__GenerateReport|0_0>d.MoveNext() in C:\Users\--\Documents\projects\ConsoleApp3\ConsoleApp3\Program.cs:line 29 column 9
at AsyncTaskMethodBuilder+AsyncStateMachineBox<VoidTaskResult,StiDictionary+<SynchronizeAsync>d__105>.ExecutionContextCallback(Object)
at AsyncTaskMethodBuilder+AsyncStateMachineBox<VoidTaskResult,StiDictionary+<SynchronizeAsync>d__105>.MoveNext(Thread)
at AsyncTaskMethodBuilder+AsyncStateMachineBox<VoidTaskResult,StiDictionary+<SynchronizeAsync>d__105>.MoveNext()
at StiReport.RenderAsync()
at AsyncTaskMethodBuilder+AsyncStateMachineBox<VoidTaskResult,StiDictionary+<SynchronizeAsync>d__105>.ExecutionContextCallback(Object)
at AsyncTaskMethodBuilder+AsyncStateMachineBox<VoidTaskResult,StiDictionary+<SynchronizeAsync>d__105>.MoveNext(Thread)
at AsyncTaskMethodBuilder+AsyncStateMachineBox<VoidTaskResult,StiDictionary+<SynchronizeAsync>d__105>.MoveNext()
Isn't there any way of optimizing those allocations?