[英]Error on using Entity Framework on released winform application
[英]Entity framework memory not released
我正在使用一个非常简单的asp.net mvc应用程序与Entity Framework 6.0.2,.Net 4.5.1:
public class HomeController : Controller
{
public ActionResult Index()
{
int count;
using (var db = new LocalContext())
{
count = db.Counters.Count();
}
return View(count);
}
}
public class Counter
{
public int Id { get; set; }
}
public class LocalContext : DbContext
{
public DbSet<Counter> Counters { get; set; }
}
如果我对它进行负载测试,我最终会得到Out of Memory异常。 ( tinyget -srv:localhost -port:<port> -uri:/home/index/ -threads:30 -loop:5000
)。 在性能监视器中,我看到第2代Heap稳步增长。 如果我使用较小的循环值(比如500),则大小会增加,直到tinyget停止。 然后堆大小保持不变(至少20分钟,之后我停止了服务器)。
我究竟做错了什么?
编辑
所以我尝试了Simon Mouriers的建议并省略了EF代码。 然后我没有记忆问题。 所以我想,也许如果我使用Release而不是Debug,它会有所作为。 它做到了! 内存在一段时间后被释放,我可以在网站上施加高负荷。 然后我切换回Debug,看看我是否可以获得更多信息......即使在调试模式下也没有问题了。 FML,我工作了一天,现在我再也无法重现了。
在您的情况下,继承自DbContext的内部托管类将需要实现IDisposable并在LocalContext内添加以下内容:
public void Dispose()
{
this.Dispose(true);
GC.SuppressFinalize(this);
}
protected virtual void Dispose(bool disposing)
{
if (disposing)
{
// Manage any native resources.
}
//Handle any other cleanup.
}
如果没有专门覆盖对dispose的调用,则using语句只会针对基类调用Dispose(),而您需要处理父类和基类。
这可能不是正确的答案,但我建议保持您的上下文由IoC容器管理。 并使用TrasientScope或PerHttpRequest范围添加它(由于ioc容器语法的多样性,未提供示例)。 如果您想要一个特定的例子,请回复您想要的DI
实际上, OutOfMemotyException
在这种情况下是正常的,因为垃圾收集器在您完成对象后不会立即发生。 在这种情况下,您需要使用GC.Collect()在所有代内存上执行集合,并立即回收所有无法访问的内存。
public class HomeController : Controller
{
public ActionResult Index()
{
int count;
using (var db = new LocalContext())
{
count = db.Counters.Count();
}
GC.Collect();
return View(count);
}
}
请注意,您不应在生产代码中使用GC.Collect() ,因为它会干扰垃圾收集机制。
我会去创建一个到DB的类连接..
public class DBconnection : IDisposable
{
private ChatEntities _db = new ChatEntities();
protected ChatEntities Db {
get { return _db; }
}
public void Dispose()
{
if (_db != null)
{
_db.Dispose();
}
}
}
然后,当你想连接和操作..让我们称之为DBlogic类..
public class DBlogic : DBconnection
{
internal void WriteToDB(String str){
//Do something ...
Db.SaveChanges();
}
}
这最终会导致Dispose清空资源..加上它的清洁剂..至少对我的眼睛来说:D
我没看到你的代码有什么问题。 也许这可能是底层ADO.NET提供程序的问题。 你使用的是哪个数据库?
我记得有些单元测试没有发布SQLite数据库文件的问题我最终用这个代码解决了(在我的DbContext类中)
public class LocalContext : DbContext
{
protected override void Dispose(bool disposing)
{
var connection = this.Database.Connection;
base.Dispose(disposing);
connection.Dispose();
}
}
可能是无关的,但我会尝试一下。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.