1
我使用EF6與SQLite數據庫。我爲每個請求創建和處理對象DBContext
,但想要緩存SQLiteConnection
對象,因此數據庫會保留在內存中。看起來EF在這種情況下會泄漏內存。實體框架6內存泄漏
這裏有一個最小的工作示例:
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
事件並且從不退訂它。
我的(非常難看)解決方法是手動「清除」 StateChange
事件每次使用後場,這樣的:
conn
.GetType()
.GetField("StateChange", System.Reflection.BindingFlags.NonPublic | System.Reflection.BindingFlags.Instance)
.SetValue(conn, null);
這是一個已知的問題?有更好的解決方法嗎?