Skip to content
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

ASP.NET Core 2.2 In-MemoryDB does not free memory even when records are deleted. #16398

Closed
vishwas-trivedi opened this issue Jul 2, 2019 · 6 comments

Comments

@vishwas-trivedi
Copy link

vishwas-trivedi commented Jul 2, 2019

Describe the bug

I tried creating a sample application to test the feature of InMemoryDatabase in asp.net core 2.2, What I found out was that even when you delete a record from in-memory database, the it does not release the memory(confirmed from task manager).

I have created following API to add and delete records from in-memory DB :

[HttpPut("{id}")]
public void Put(int id)
{
    // Create 100 MB Data
    var result = new Result()
    {
        Id = id,
        Data = new string('*', 100 * 1024 * 1024)
    };

    _context.Result.Add(result);
    _context.SaveChanges();
}

[HttpDelete("{id}")]
public void Delete(int id)
{
    var result = _context.Result.Find(id);
    if (result != null)
    {
        _context.Result.Remove(result);
        _context.SaveChanges();
    }
    else
    {
        throw new Exception("id not found!");
    }
}

My Startup.cs file looks like following :

public class Startup
{
    public Startup(IConfiguration configuration)
    {
        Configuration = configuration;
    }

    public IConfiguration Configuration { get; }

    // This method gets called by the runtime. Use this method to add services to the container.
    public void ConfigureServices(IServiceCollection services)
    {
        services.AddMvc().SetCompatibilityVersion(CompatibilityVersion.Version_2_2);
        services.AddDbContext<MyDbContext>(opt =>
           opt.UseInMemoryDatabase("TestMemoryDb").UseQueryTrackingBehavior(QueryTrackingBehavior.NoTracking));
    }

    // This method gets called by the runtime. Use this method to configure the HTTP request pipeline.
    public void Configure(IApplicationBuilder app, IHostingEnvironment env)
    {
        if (env.IsDevelopment())
        {
            app.UseDeveloperExceptionPage();
        }
        else
        {
            // The default HSTS value is 30 days. You may want to change this for production scenarios, see https://aka.ms/aspnetcore-hsts.
            app.UseHsts();
        }

        app.UseHttpsRedirection();
        app.UseMvc();
    }
}

To Reproduce

Steps to reproduce the behavior:

  1. Create an ASP.NET core application using above code.
  2. Run the code.
  3. Check memory usage in task manager.
  4. Add a few records.
  5. Check memory usage in task manager, it should be increased.
  6. Delete a few records.
  7. Check memory usage in task manager(memory used will not change).

Expected behavior

It should clear the memory for the deleted records.

Additional Info

VS 2019's Diagnostic Tools shows the similar result, Process memory increases on put but does not decrease on delete.

Question

Have I made any mistake in settings or understanding the in-memory DB?
Is this expected behavior?

Any help would be appreciated.
Regards.

@vishwas-trivedi vishwas-trivedi changed the title ASP.NET 2.2 In-MemoryDB does not free memory even when records are deleted. ASP.NET Core 2.2 In-MemoryDB does not free memory even when records are deleted. Jul 2, 2019
@dcarr42
Copy link

dcarr42 commented Jul 2, 2019

It will not reclaim memory during normal usage. I would question whether it will release memory even under high gc pressure. The database is rooted as a dependency tied to the the service provider so it will be held across contexts.

@Eilon
Copy link
Member

Eilon commented Jul 2, 2019

@ajcvickers / @divega / @smitpatel - should this move to the EF repo? (Even if by-design.)

@ajcvickers ajcvickers transferred this issue from dotnet/aspnetcore Jul 2, 2019
@ajcvickers
Copy link
Member

@vishwas-trivedi This is generally not a good way to determine if there is a memory leak since the memory will not be reclaimed in an immediate and predictable manner.

@vishwas-trivedi
Copy link
Author

@ajcvickers Okay, what do you suggest?
Also, Memory might not be reclaimed immediately but I believe it should be reclaimed when the application(server) is idle. I tried waiting for 1-2 hours without any action but there was no change. GC just didn't execute.

I know the usual argument here is "GC will kick-in when there is a shortage of memory" but isn't there any better way to handle this without waiting for the memory to become scarce?

Regards,
Vishwas

@ajcvickers
Copy link
Member

@vishwas-trivedi If you would like to follow up on how the garbage collector works, then please go to https://github.com/dotnet/coreclr

If you would like to pursue the possible leak in EF Core, then please create a small, runnable project/solution or complete code listing that demonstrates the leak even after garbage collection has been forced.

@vishwas-trivedi
Copy link
Author

@ajcvickers Okay, thank you for the suggestion. I was able to confirm that GC does collect the unused memory when forced called.

Regards,
Vishwas

@ajcvickers ajcvickers reopened this Oct 16, 2022
@ajcvickers ajcvickers closed this as not planned Won't fix, can't repro, duplicate, stale Oct 16, 2022
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

4 participants