Memory leak with Aspose.svg in C# .Net 5

I call the followed method in an api service and try to use Aspose.Svg library to create an Aspose.svg document:

 public async Task<PlanGroupCategory> UploadPlanAsync(byte[] byteStream, string mimeType)
 {
        if (byteStream == null)
            throw new Exception("Hinzugefügte Dateien sind leer.");

        using (MemoryStream stream = new MemoryStream(byteStream))
        {
            if (stream == null)
                throw new BauDrException("Svg Document ist leer.");
            stream.Seek(0, SeekOrigin.Begin);
            using (var document = new SVGDocument(stream, "."))
            {
                (...)
            }
        }
 }

After call using (var document = new SVGDocument(stream, “.”)) the application (ASP.NET 5) consums a lot of unmanaged memory. The memory jump from 200 MB to ± 1,3 GB and it will never be freed. After repeat the use case the memory goes up. The uploaded svg file from client is 2,6 MB. The memory leak was checked with visual studio diagnostics and JetBrains dotmemory. After calling the garbage collector the memory is not released. The call of individual “dispose” did not work either.

As described in stackoverflow (https://stackoverflow.com/questions/67065731/memory-leak-with-aspose-svg), I post the memory leak right here in forum.
Used svg fie: 200911_OG1_Komplett.zip (172.9 KB)

@anis3h

We have tested the scenario in our environment while using Aspose.SVG for .NET 21.4 and noticed that the memory consumption was 200MB to 500MB and it went down after the SVG file was loaded. Could you please confirm if you are also using the latest version of the API. If so is the case and issue is still happening at your end, please share a sample console application with us which is able to replicate the same behavior. We will further proceed to assist you accordingly.

Thank you for your answer.
I tested the case with the last SVG .Net 21.4.
If I set a breakpoint before calling the following method:

public async Task UploadPlanAsync(byte[] byteStream, string mimeType, string fileName, Guid planGroupCategoryId)
{
if (byteStream == null)
throw new Exception(“Error.”);

        using (MemoryStream stream = new MemoryStream(byteStream))
        {
            if (stream == null)
                throw new Exception("Error.");
            //stream.Write(byteStream, 0, byteStream.Length);
            stream.Seek(0, SeekOrigin.Begin);
             //Breakpoint  !!!!!
                **using (var document = new SVGDocument(stream, "."))**
            {
                       (.....)
            }

}

After one step the memory looks like this:
Memory_Leak.png (32.2 KB)

I use the following technologies:
Angular 11 in frontend.
Asp.Net 5 (last version) in backend

The API Controller in ASP.Net 5 is look like this:

    [HttpPost, DisableRequestSizeLimit]
    [Route("upload/plancategories/{plangroupid}/plans")]
    public async Task<ActionResult<PlanGroupCategoryDto>> UploadPlan([FromRoute(Name = "plangroupid")] Guid planGroupId)
    {
        if (!ModelState.IsValid)
        {
            return BadRequest("Error.");
        }

        var file = Request.Form.Files[0];

        byte[] byteStream;
        using (MemoryStream memoryStream = new MemoryStream())
        {
            using (var stream = file.OpenReadStream())
            {
                await stream.CopyToAsync(memoryStream);
                byteStream = memoryStream.ToArray();
                var mimeType = file.ContentType;
                var fileName = file.FileName;

                var blob = new Blob
                {
                    FileName = fileName,
                    MimeType = mimeType,
                    BlobContent = new BlobContent { Content = byteStream }
                };

                var result = await _plansService.UploadPlanAsync(byteStream, mimeType, fileName, planGroupId);
                (...)
            }
        }
    }

The api controller is called from angular client with the svg file.
Can you share your sample console, please?

@anis3h

We are checking it and will get back to you shortly.

Could you reproduce my issue? I would be very grateful for a short response of the current status of my post.
Thank you.
Best regards

@anis3h

We again tried to reproduce the issue by loading your SVG file using Streams and could not replicate the issue of memory leak. It looks like the issue is due to specific routine of your application. Could you please share a sample console or web application which can mimic the routine of your workflow and replicate the same issue that you are facing? We will surely again test the scenario in our environment and address it accordingly.

Hi,
I have memory leak too here there is my code.

@ asad.ali

const string svgString = "<svg xmlns=\"http://www.w3.org/2000/svg\" width=\"467\" height=\"462\">  <rect x = \"80\" y=\"60\" width=\"250\" height=\"250\" rx=\"20\"      style=\"fill:#ff0000; stroke:#000000;stroke-width:2px;\" />    <rect x = \"140\" y=\"120\" width=\"250\" height=\"250\" rx=\"40\"      style=\"fill:#0000ff; stroke:#000000; stroke-width:2px;      fill-opacity:0.7;\" /></svg>";
    static void Main(string[] args)
    {
        var line = "r";
        while (line == "r")
        {
            for (int y = 0; y < 10; y++)
            {
                using (var svgDocument = new SVGDocument(svgString, ""))
                {
                    // Initialize an instance of PdfRenderingOptions class and set a custom PageSetup and JpegQuality properties
                    var pdfRenderingOptions = new PdfRenderingOptions();
                    pdfRenderingOptions.PageSetup.AnyPage = new Page(new Size(200, 200), new Margin(0, 0, 0, 0));
                    pdfRenderingOptions.JpegQuality = 100;

                    using (Stream stream = new MemoryStream())
                    {
                        // Initialize an instance of PdfDevice class
                        using (PdfDevice device = new PdfDevice(pdfRenderingOptions, stream))
                        {
                            // Render SVG to PDF, send the document to the rendering device
                            svgDocument.RenderTo(device);
                        };
                    }
                }
            }
            Console.WriteLine("Press 'r' and 'ENTER' to repeat");
            line = Console.ReadLine();
        }
    }

TestMemoryLeakAspireSvg.zip (3.3 MB)

@agai

We were able to notice the memory consumption issue while testing the scenario using your console application. We have logged it as SVG-129 in our issue tracking system for the sake of correction. We will look into its details and keep you posted with the status of its correction. Please be patient and spare us some time.

We are sorry for the inconvenience.

@asad.ali
There is the code to reproduce the memory leak:

class Program
{
static void Main(string[] args)
{
string path = Directory.GetCurrentDirectory();
string contents = File.ReadAllText($"{path}" + @"\200911_OG1_Komplett.svg");

        for (int i = 0; i < 5; i++)
        {
            ReproduceMemoryLeak(contents);
        }
    }

    private static void ReproduceMemoryLeak(string contents)
    {
        using (var svgDocument = new SVGDocument(contents, ""))
        {

        }
    }
}

There is the VS solution:
ConsoleApp1.zip (183.7 KB)

Screenshot to memory leak: MemoryLeak.jpg (198.1 KB)

After my tests the memory leak problem occures with the folllowing project settings:

>  <PropertyGroup>
>     <ServerGarbageCollection>true</ServerGarbageCollection>
>   </PropertyGroup> 

There is no memory leak with ServerGarbageCollection = false.

@anis3h

We have updated the ticket information as per your provided information. We will surely consider it and investigate the issue from this perspective. We will inform you once the ticket is resolved.

We apologize for the inconvenience.