Local variable in async method holding EF loaded data is not garbage collected #105859
Unanswered
Cerberus4444
asked this question in
Q&A
Replies: 2 comments 2 replies
-
In your code public async Task RetrieveConfigurationFiles()
{
await using (MandantDbContext mandantDbContext = new(
new DbContextOptionsBuilder<MandantDbContext>()
.UseSqlServer(%CONNECTIONSTRING%)
.Options))
{
DbSet<ConfigurationFile> dbSet = mandantDbContext.Set<ConfigurationFile>();
List<ConfigurationFile> configurationFiles = await dbSet
.AsNoTracking()
.ToListAsync(CancellationToken.None);
// Try clearing the reference to help GC
configurationFiles = null;
}
// Force GC
GC.Collect();
GC.WaitForPendingFinalizers();
GC.Collect();
} |
Beta Was this translation helpful? Give feedback.
1 reply
-
Not sure if this is always correct, but from my experience local variables won't get garbage collected if the method hasn't returned yet. You need to move |
Beta Was this translation helpful? Give feedback.
1 reply
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
-
I have noticed a behavior that I didn't quite expect.
When I load data asynchronously from a DbContext using EF and store it into a local variable, the memory will not get garbage collected after the method completed execution.
I have made a very small sample method to verify the behavior:
DotMemory shows that the space on Heap generation 2 does not get freed up even after nullification of the variable and forced gc:
When I check the retention, DotMemory shows that most of these objects seem to be held by the async state machine.
Now the really weird part:
Even minutes after the method completed, when I force gc with DotMemory, the memory cannot be freed up.
It will keep around 600 MB in Heap generation 2.
When I run the method multiple times, "Heap generation 2" grows to around 1 GB before the added pressure on the memory seems to force a cleanup, bringing it down to around 600 MB again.
600 MB that again seems to be immune to forced gc.
This problem with the memory not being freed up by forced gc seems to be specific to this EF data loading.
A rather simple asynchronous memory allocation like this does not have the same problem:
byte[] configurationFiles = await Task.FromResult(new byte[1000000000000]);
Is there a specific memory retention behavior for data loaded with EF with async/await?
Thanks for your help.
Beta Was this translation helpful? Give feedback.
All reactions