MVC EF6
Привет, я нигде не смог найти ответ на этот вопрос, поэтому я отправляю свой вопрос, я пытаюсь отследить утечку памяти, в ней много повторяющихся строкмое приложение, приложение, с которым я работаю, ДЕЙСТВИТЕЛЬНО БОЛЬШОЕ, в нем МНОГО кода.
Я понял, что каждый раз, когда делается запрос, мы создаем новый экземпляр БД-контекста, но мы никогда не избавляемся от него, поэтому просто проверим это в моем списке и убедитесь, что все удалено.
Пожалуйста, не публикуйте что-то подобное, просто сделайте следующее:
using(var context = new DbContext) {}
Я не могу этого сделать, потому что приложение ОГРОМНО, а рефакторинг займет ОЧЕНЬ много времени.Один из вариантов, который я решил сделать, - создать словарь, а затем сохранять контекст при каждом запросе следующим образом (Global asax):
protected void Application_EndRequest(object sender, EventArgs e)
{
if (User != null && User.Identity.IsAuthenticated)
{
ContextConfig.Dispose(Context.Items["UniqueRequestId"].ToString());
}
}
protected void Application_BeginRequest(Object sender, EventArgs e)
{
//Creating Unique Request ID
Context.Items["UniqueRequestId"] = Guid.NewGuid().ToString();
}
Здесь я создаю уникальный идентификатор для запроса, а затем в конце располагаюлюбой контекст, который был создан во время этого запроса (да, я знаю, что он должен быть только один на запрос, но они создают больше 1, но максимум, который я видел, равен 2, так что это не так уж и плохо).
Это мой класс ContextConfig:
public static class ContextConfig
{
private static ConcurrentDictionary<string, List<DbContext>> Config = new ConcurrentDictionary<string, List<DbContext>>();
public static void Add(string key, DbContext context)
{
//If contains key then add it, otherwise just create new instance
if (Config.ContainsKey(key))
{
Config[key].Add(context);
}
else
{
Config[key] = new List<DbContext>();
Config[key].Add(context);
}
}
public static void Dispose(string key)
{
//If contains key and list has context then dispose them.
if (Config.ContainsKey(key))
{
if (Config[key] != null && Config[key].Count > 0)
foreach (var context in Config[key])
{
context.Dispose();
}
Config[key].Clear();
((IDictionary)Config).Remove(key);
}
}
}
После этого я ожидал увидеть улучшение в моей проблеме с MemoryLeak, но я думаю, что это как-то ухудшило ситуацию, потому что по некоторым причинамдобавленные в список были проведены сборщиком мусора и теперь я потерялся.
Вот что я вижу в профиле памяти:
Это все повторяющиеся строки:
РЕДАКТИРОВАТЬ: Не уверен, что это актуально или нет, но когда я создаю новый экземпляр, это происходит
context.Configuration.AutoDetectChangesEnabled = true;
context.Configuration.ProxyCreationEnabled = false;
context.Configuration.LazyLoadingEnabled = false;