Skip to content

Memory leak #10771

Closed
Closed
@ADD-Eugenio-Lopez

Description

@ADD-Eugenio-Lopez

We want to send files using a web application on asp.net core with a kestrel. We have programmed a controller that responds to httpget and returns files that we keep in a MemoryCache.
When the MemoryCache was loaded, we made several requests for the 162 files it contains and observed that the memory of the process does not stop growing at each request.
We have implemented the Response.OnComplete to Dispose the MemoryStream used and make a GarbageCollector, with this we have improved the use of memory and now the increase in the use of memory is about 300 KB per request. This is a problem in case of thousands of requests.
We have executed the performance of VisualStudio and making comparisons between each call, it does not show differences in the use of memory but in the TaskManager the process does not stop growing.
Any idea what the problem might be?

Here is our file to send files:

    /// <summary> Gets a file from cache. </summary>
    /// <param name="fileName"> Filename of the file. </param>
    /// <returns> The file to return. </returns>
    private ActionResult GetFile(string fileName)
    {
        ICacheEntry memoryEntry;

        if (this.memoryCache.TryGetValue(fileName, out memoryEntry))
        {
            // Gets original stream from the cache.
            Stream originalStream = (Stream)memoryEntry.Value;

            Stream stream = new MemoryStream();

            // Copy stream to new one because after send to client it is closed.
            originalStream.CopyTo(stream);

            // Restart positions of streams.
            originalStream.Seek(0, SeekOrigin.Begin);
            stream.Seek(0, SeekOrigin.Begin);

            // Configures the event OnCompleted request to dispose stream object.
            Response.Headers["Content-Disposing"] = "attachment";

            Response.OnCompleted(() =>
            {
                stream.Dispose();
                stream = null;

                // Calls Garbage Collector to free memory, in other case it is not freed.
                System.GC.Collect();

                return Task.CompletedTask;
            });

            // The content type parameter depends on file type.
            if (fileName.EndsWith(".application"))
            {
                return new FileStreamResult(stream, "application/x-ms-application");
            }

            if (fileName.EndsWith(".manifest"))
            {
                return new FileStreamResult(stream, "application/x-ms-manifest");
            }

            return new FileStreamResult(stream, "application/octet-stream");
        }

        return null;
    }

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions