繁体   English   中英

为什么 EF Core 2.2.6 不进行垃圾回收?

[英]Why EF Core 2.2.6 does not garbage collect?

我正在使用 dotMemoryUnit 来证明我的 DbContext 对象正在正确收集垃圾。

我觉得这段代码在单元测试中应该可以正常工作,但是测试总是失败。 我唯一能猜到的是 EF Core 在某处持有引用。

编辑:我不确定建议的问题是否解决了这个问题,因为这是 .Net Core 而不是 .Net Framework。 GC.Collect() 的默认文档是强制的,文档没有说明提示。

编辑2:我确实在下面找到了答案。

想法?

    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)
            {
            }
        }
    }

经过更多的研究,我在 Jet Brains 的这篇文章中找到了答案:

由于我们所有的逻辑都在一个方法(我们的测试方法)中运行,垃圾收集器不会清理在我们的函数上下文中仍然可用的局部变量。

该帖子建议将代码包装在操作方法中。

对于可能有此问题的其他人,以下是我的新测试方法:

[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));
}

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM