我有一个连接到某些数据库的应用程序。首次执行后,该应用需要300Mb(一些数据正在从数据库中加载),并且可以。但是,在按下“刷新”按钮后,调用了刷新方法,在该方法中,我用新集合重新分配了旧集合,问题是它们在加载新数据后-旧数据仍在占用内存,因此在进行一些强制刷新之后,它可能占用2Gb。
我尝试用不同的选项来强制GC-什么也没发生。 GC认为我的收藏集不需要完全更新,而旧数据必须销毁。
我决定创建自己的Disposable集合,该集合继承自List或Collection并实现IDisposable [1]。然后,我抛出了所有类,这些类都包含在此类集合中,并且也实现了IDisposable(带有和不带有析构函数)。
我曾经使用过using()构造来清除那些集合[2],但是结果是集合已经变空了,但是仍然占用了内存。
使用配置文件程序,我看到每次刷新时Gen0对象的数量都会增加。刷新10次后,有120至580个此类对象,GC无法清除。
编辑:
因此8处于“刷新”方法,并且每次刷新时都会重新分配数据。
[1]
public class DisposableList<T> : List<T>, IDisposable where T :
IDisposable
{
public DisposableList()
{
}
public DisposableList(T instance)
{
Add(instance);
}
public DisposableList(IEnumerable<T> instances)
{
AddRange(instances);
}
protected virtual void Dispose(bool disposing)
{
if (disposing)
{
foreach (T item in this)
{
item.Dispose();
}
}
}
public void Dispose()
{
Dispose(true);
}
~DisposableList()
{
}
}
[2]
using (Resources = new DisposableList<Resources>())
{
}
[3]
public partial class MyDataContext : DbContext, IMyDataContext
{
static MyDataContext()
{
Database.SetInitializer<MyDataContext>(null);
}
public MyDataContext(string connectionString)
: base(connectionString)
{
try
{
if (!Database.Exists())
{
throw new Exception($"Нет соединения с базой данных
{Database.Connection.Database}");
}
}
catch (Exception ex)
{
throw ex;
}
}
public IDbSet<Table> Table { get; set; }
}
[4]
public class UnitOfWork : IUnitOfWork
{
DbContext _dataContext;
IRepository[] _repositories;
readonly object _locked = new object();
public UnitOfWork(DbContext dataContext, params IRepository[]
repositories)
{
_dataContext = dataContext;
_repositories = repositories;
EFContextHelper.SetContext(_repositories, dataContext);
}
public virtual void SaveChanges()
{
try
{
lock (_locked)
{
_dataContext.SaveChanges();
}
}
catch (DbUpdateConcurrencyException ex)
{
throw;
}
catch (Exception ex)
{
throw;
}
}
public virtual bool HasChanges()
=> _dataContext.ChangeTracker.HasChanges();
public virtual void Rollback()
{
lock (_locked)
{
foreach (DbEntityEntry entry in
_dataContext.ChangeTracker.Entries())
{
switch (entry.State)
{
case EntityState.Detached: break;
case EntityState.Unchanged: break;
case EntityState.Added:
entry.State = EntityState.Detached;
break;
case EntityState.Deleted:
entry.State = EntityState.Unchanged;
break;
case EntityState.Modified:
entry.CurrentValues.SetValues(entry.OriginalValues);
entry.State = EntityState.Unchanged;
break;
default:
throw new ArgumentOutOfRangeException();
}
}
}
}
#region IDispose
bool _disposed;
public virtual void Dispose()
{
if (_disposed) { return; }
foreach (var repo in _repositories)
{
repo.Dispose();
}
_dataContext?.Dispose();
_dataContext = null;
_disposed = true;
}
[5]
public interface IRepository<TEntity> : IRepository where TEntity : class
{
TEntity Create();
void Delete(TEntity entity);
void Delete(IEnumerable<TEntity> entities);
void AddOrUpdate(TEntity entity);
void Attach(TEntity entity);
void Reload(TEntity entity);
void Detach(TEntity entity);
}
[6]
builder.RegisterType<Service>().As<IService>();
builder.RegisterType<Repository>).As<Repository>;
[7]
GetData()
{
using (_UnitOfWorkFactory.Create(_repository))
{
var data = _repository.Get();
}
}
[8]
var service = Bootstrapper.Container.Resolve<IService>();
var data = service.GetData();
因此,我需要我的应用使用这样的内存量,该内存量是在首次执行后使用的。我希望我的旧数据被销毁,新数据取代旧数据。