我将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);
这是一个已知问题吗?有更好的解决方法吗?
答案 0 :(得分:1)
我遇到了同样的问题。在EntityConnection上调用Dispose()似乎可以解决问题。
bad_alloc