dotnet / dotnet/aspnetcore

ApiController: memory leak when returning large string arrays

Open
#55,179 2 comments 1 reaction 0 assignees View on GitHub
area-mvc
Dominant language
C#
Stars
38.4k
Forks
10.9k
Avg merge
2d 6h
Merged PRs (30d)
290

Description

### Is there an existing issue for this?

- [X] I have searched the existing issues

### Describe the bug

When returning a large string in my ApiController, the process memory goes up. But even after the garbage collector was triggered (manually or automatically), the memory doesn't fall back like you expect.

A small code example is listed below. The full minimal project is linked further down.

```cs
[HttpGet("memory")]
[OutputCache(Duration = 0, NoStore = true)]
public IEnumerable Memory()
{
List list = new();

for (var i = 0; i < 1_000_000; i++)
{
list.Add(i.ToString());
}

return list;
}
```
![image](https://github.com/dotnet/aspnetcore/assets/31313717/0cd74f37-73e6-4fc8-9f58-fb99f817e96d)

### Expected Behavior

I expect the memory to fall back. When I also create a list in a small console application, the memory falls back like expected. This console project is listed below and in the reproduce repo I linked.
```cs
while (true)
{
GC.Collect();
GC.WaitForPendingFinalizers();
Console.ReadLine();

var list = GetList();
Console.WriteLine(list.Count);
}
List GetList()
{
List list = new();
for (int i = 0; i < 1_000_000; i++)
{
list.Add(i.ToString());
}

return list;
}
```
![image](https://github.com/dotnet/aspnetcore/assets/31313717/0560b360-81ba-4631-986c-3300272fc2bd)

### Steps To Reproduce

I created a minimalistic project in the following repository: https://github.com/Paultje52/aspnet-string-array-memory-issue

This repository consists of two project: `WebApplication` with the issue in an ApiController and `ConsoleApp` with the expected behaviour in a console application.

Go to the page [`http://localhost:5100`](http://localhost:5100) to get the list and trigger the memory issue. After making that request multiple times, go to [`http://localhost:5100/collect`](http://localhost:5100/collect) to manually trigger the garbage collector.

### Exceptions (if any)

_No response_

### .NET Version

8.0.202

### Anything else?

ASP.NET Core: `8.0.3`

IDE: `Visual Studio 17.9.5`

Dotnet info

```
.NET SDK:
Version: 8.0.202
Commit: 25674bb2f4
Workload version: 8.0.200-manifests.8cf8de6d

Runtime Environment:
OS Name: Windows
OS Version: 10.0.22631
OS Platform: Windows
RID: win-x64
Base Path: C:\Program Files\dotnet\sdk\8.0.202\

.NET workloads installed:
There are no installed workloads to display.

Host:
Version: 8.0.3
Architecture: x64
Commit: 9f4b1f5d66

.NET SDKs installed:
8.0.202 [C:\Program Files\dotnet\sdk]

.NET runtimes installed:
Microsoft.AspNetCore.App 6.0.28 [C:\Program Files\dotnet\shared\Microsoft.AspNetCore.App]
Microsoft.AspNetCore.App 7.0.17 [C:\Program Files\dotnet\shared\Microsoft.AspNetCore.App]
Microsoft.AspNetCore.App 8.0.3 [C:\Program Files\dotnet\shared\Microsoft.AspNetCore.App]
Microsoft.NETCore.App 6.0.28 [C:\Program Files\dotnet\shared\Microsoft.NETCore.App]
Microsoft.NETCore.App 7.0.17 [C:\Program Files\dotnet\shared\Microsoft.NETCore.App]
Microsoft.NETCore.App 8.0.3 [C:\Program Files\dotnet\shared\Microsoft.NETCore.App]
Microsoft.WindowsDesktop.App 6.0.28 [C:\Program Files\dotnet\shared\Microsoft.WindowsDesktop.App]
Microsoft.WindowsDesktop.App 7.0.17 [C:\Program Files\dotnet\shared\Microsoft.WindowsDesktop.App]
Microsoft.WindowsDesktop.App 8.0.3 [C:\Program Files\dotnet\shared\Microsoft.WindowsDesktop.App]

Other architectures found:
x86 [C:\Program Files (x86)\dotnet]
registered at [HKLM\SOFTWARE\dotnet\Setup\InstalledVersions\x86\InstallLocation]

Environment variables:
Not set

global.json file:
Not found

Learn more:
https://aka.ms/dotnet/info

Download .NET:
https://aka.ms/dotnet/download
```

Contributor guide

Open the contributing guide

Assessment

This issue has not been assessed yet.

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.