实体框架6内存泄漏

时间:2016-11-12 13:16:57

标签: c# entity-framework memory-leaks

我将EF6与SQLite数据库一起使用。我为每个请求创建并处理DBContext个对象,但是我希望缓存SQLiteConnection个对象,因此数据库会保留在内存中。看起来好像EF在这些情况下会泄漏内存。

这是一个最小的工作样本:

class Program
{
    static void Main(string[] args)
    {
        // use one connection for the lifetime of the application
        using (var conn = new System.Data.SQLite.SQLiteConnection("Data Source=:MEMORY:"))
        {
            // create sample DB
            conn.Open();
            using (var context = new MyContext(conn, false))
                context.Database.ExecuteSqlCommand("CREATE TABLE SomeTable(Id INTEGER PRIMARY KEY AUTOINCREMENT)");

            while (true)
            {
                // access database 
                using (var context = new MyContext(conn, false))
                {
                    var x = System.Linq.Enumerable.Count(context.SomeTable);
                }
                // show memory usage
                System.Console.Write("{0:0,0} Bytes   \r", System.GC.GetTotalMemory(false));
            }
        }
    }
}

class MyContext : System.Data.Entity.DbContext
{
    public MyContext(System.Data.Common.DbConnection existingConnection, bool contextOwnsConnection)
        : base(existingConnection, contextOwnsConnection)
    { }

    public System.Data.Entity.DbSet<SomeTableRow> SomeTable { get; set; }
}

[System.ComponentModel.DataAnnotations.Schema.Table("SomeTable")]
class SomeTableRow
{
    public int Id { get; set; }
}

如果我运行它,进程内存使用量会不断增加。

我认为问题是System.Data.Entity.Core.EntityClient.EntityConnection订阅了连接对象上的StateChange事件,并且永远不会取消订阅。

我(非常难看)的解决方法是手动&#34;清除&#34;每次使用后的StateChange事件字段,如下所示:

conn
    .GetType()
    .GetField("StateChange", System.Reflection.BindingFlags.NonPublic | System.Reflection.BindingFlags.Instance)
    .SetValue(conn, null);

这是一个已知问题吗?有更好的解决方法吗?

1 个答案:

答案 0 :(得分:1)

我遇到了同样的问题。在EntityConnection上调用Dispose()似乎可以解决问题。

bad_alloc