Why EF Core 2.2.6 does not garbage collect?

可紊 提交于 2020-08-08 05:31:38

问题


I am using the dotMemoryUnit to prove the my DbContext object is getting garbage collected properly.

I feel that this code should work properly in a unit test, but the test always fails. The only thing I can guess is EF Core is holding a reference somewhere.

Edit: I'm not sure the suggested question addresses this problem as this is .Net Core and not .Net Framework. The documentation for GC.Collect()'s default is forced and the documentation says nothing about hints.

Edit 2: I did find the answer below.

Thoughts?

    public class UnitTest1
    {
        public UnitTest1(ITestOutputHelper output)
        {
            DotMemoryUnitTestOutput.SetOutputMethod(output.WriteLine);
        }

        [Fact]
        [DotMemoryUnit(FailIfRunWithoutSupport = false)]
        public void DummyContext_DisposesContextOnGarbageCollect()
        {
            // Arrange
            var options = new DbContextOptionsBuilder<DummyContext>()
                .UseSqlServer("data source=ASqlServer;Integrated Security=true");

            using (var ctx = new DummyContext(options.Options))
            {
                // do nothing
            }

            GC.Collect();
            GC.WaitForPendingFinalizers();

            dotMemory.Check(
                memory =>
                    Assert.Equal(
                        0,
                        memory.GetObjects(where => where.Type.Is<DummyContext>()).ObjectsCount));
        }

        private class DummyContext : DbContext
        {
            public DummyContext(DbContextOptions options)
                : base(options)
            {
            }
        }
    }


回答1:


After a little more research, I have found the answer in this post from Jet Brains:

Since all of our logic is being run in one method (our test method), the garbage collector will not clean up local variables that are still available in the context of our function.

The post suggests wrapping the code in an action method.

For others that may have this problem, below is my new test method:

[Fact]
[DotMemoryUnit(FailIfRunWithoutSupport = false)]
public void DummyContext_DisposesContextOnGarbageCollect()
{
    var isolator = new Action(
        () =>
        {
            // Arrange
            var options = new DbContextOptionsBuilder<DummyContext>()
                .UseSqlServer("data source=ASqlServer;Integrated Security=true");

            using (var ctx = new DummyContext(options.Options))
            {
                // do nothing
            }
        });

    isolator();

    GC.Collect();
    GC.WaitForPendingFinalizers();

    SetProcessWorkingSetSize(System.Diagnostics.Process.GetCurrentProcess().Handle, -1, -1);

    dotMemory.Check(
        memory =>
            Assert.Equal(
                0,
                memory.GetObjects(where => where.Type.Is<DummyContext>()).ObjectsCount));
}


来源:https://stackoverflow.com/questions/59570078/why-ef-core-2-2-6-does-not-garbage-collect

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!