-
Notifications
You must be signed in to change notification settings - Fork 3.2k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Memory consumption, memory leaks #35369
Comments
Your sample includes lots of components, such as GraphQL, ASP.NET, etc. To relliably benchmark and isolate EF specifically, please extract the EF code into a minimal BenchmarkDotNet benchmark, using the |
BTW I'm noticing that you're instantiating 100k objects for the seeding, that in itself will already use up quite a lot of memory, which the GC won't necesary recollect right away (if it doesn't need to). I'd advise using a memory profiler to see what the actual objects are which take up memory. You can also extract out the seeding to an external program, to isolate that as well. |
I'm just getting familiar with BenchmarkDotNet, and I'm not quite sure what to use to indicate that something remains in memory after disposal. Perhaps the following code will be helpful: long memoryBeforeInsert = GC.GetTotalMemory(forceFullCollection: false);
using (var context = CreateDbContext())
{
EmployeeSeeder.Seed(context);
}
long memoryAfterInsert = GC.GetTotalMemory(forceFullCollection: false);
GC.Collect();
GC.WaitForPendingFinalizers();
GC.Collect();
long memoryAfterDispose = GC.GetTotalMemory(forceFullCollection: false);
Console.WriteLine($"Memory Before Insert: {memoryBeforeInsert} bytes");
Console.WriteLine($"Memory After Insert: {memoryAfterInsert} bytes");
Console.WriteLine($"Memory After Dispose: {memoryAfterDispose} bytes");
memoryBeforeInsert = GC.GetTotalMemory(forceFullCollection: false);
using (var context = CreateDbContext())
{
EmployeeSeeder.Seed(context);
}
memoryAfterInsert = GC.GetTotalMemory(forceFullCollection: false);
GC.Collect();
GC.WaitForPendingFinalizers();
GC.Collect();
memoryAfterDispose = GC.GetTotalMemory(forceFullCollection: false);
Console.WriteLine($"Memory Before Insert: {memoryBeforeInsert} bytes");
Console.WriteLine($"Memory After Insert: {memoryAfterInsert} bytes");
Console.WriteLine($"Memory After Dispose: {memoryAfterDispose} bytes"); Output: Memory Before Insert: 1613968 bytes When I Use memoryDiagnoser [MemoryDiagnoser]
public class EfCoreMemoryUsageBenchmark
{
private const int RecordCount = 1000;
[Benchmark]
public void WithSaveChanges()
{
using (var context = CreateDbContext())
{
EmployeeSeeder.Seed(context);
}
return;
}
[Benchmark]
public void WithoutSaveChanges()
{
using (var context = CreateDbContext())
{
EmployeeSeeder.SeedWithoutSaveChanges(context);
}
return;
}
private EmployeeContext CreateDbContext()
{
var options = new DbContextOptionsBuilder<EmployeeContext>()
.UseSqlServer("Server=localhost;Database=EmployeesDatabase;Trusted_Connection=True;TrustServerCertificate=True;")
.Options;
return new EmployeeContext(options);
}
} I got:
|
BenchmarkDotNet's [MemoryDiagnoser] tells you how much memory was allocated for each iteration, not whether that memory still stays referenced (i.e. a memory leak). To know which objects are still referenced (and so detect a possible memory leak), you can use a memory profiler such as the one included inside VS, DotMemory, or similar. To be sure I understand, what is it that you think you're seeing here, unreasonable memory consumption, a memory leak, or otherwise? It's a bit difficult to tell. |
Memory consumption, memory leaks after db operations
Code
Sample: https://github.com/Meteoeoeo/memory_consumption
after the first RunSeeder call the consumption increases significantly, in the next ones it increases but less
without batches the consumption is greater
some queries from logs
Include provider and version information
EF Core version: 8.0.11
Database provider: Microsoft.EntityFrameworkCore.SqlServer
Target framework: .NET 8.0
Operating system: Windows 11, Windows Server 2019
The text was updated successfully, but these errors were encountered: