4

У меня есть приложение ASP.NET MVC, которое создает Linq2SQL datacontext для каждого веб-запроса с использованием Castler Windsor IoC.Linq to SQL DataContext Windsor IOC проблема с утечкой памяти

По какой-то причине я не полностью понимаю, каждый раз, когда создается новый datacontext (на каждом веб-запросе), около 8 тыс. Памяти занято и не выпущено, что неизбежно вызывает исключение OutOfMemory.

Если я заставляю сбор мусора, память отпускается ОК.

Мой класс DataContext очень прост:

public class DataContextAccessor : IDataContextAccessor 
{ 
    private readonly DataContext dataContext; 
    public DataContextAccessor(string connectionString) 
    { 
     dataContext = new DataContext(connectionString);   
    } 
    public DataContext DataContext { get { return dataContext; } } 
} 

Виндзор IoC WebConfig инстанцировать это выглядит так:

<component id="DataContextAccessor" 
      service="DomainModel.Repositories.IDataContextAccessor, DomainModel" 
      type="DomainModel.Repositories.DataContextAccessor, DomainModel" 
      lifestyle="PerWebRequest">  
    <parameters> 
     <connectionString> 
     ... 
     </connectionString> 
    </parameters> 
    </component> 

Кто-нибудь знает, в чем проблема, и как это исправить?

+1

См. Http://stackoverflow.com/questions/85183/windsor-container-how-to-force-dispose-of-an-object http://stackoverflow.com/questions/132940/why-does- замок-Виндзорский-держать-на-переходными-объектов –

ответ

6

L2S DataContext реализует IDisposable. Ваш интерфейс также должен реализовать его и вызвать DataContext.Dispose(), чтобы Windsor знал, что есть ресурсы, которые нужно утилизировать.

Кстати остерегаться Виндзор/IDisposable проблемы: http://www.jeremyskinner.co.uk/2008/05/03/aspnet-mvc-controllers-windsor-and-idisposable/ http://www.nablasoft.com/Alkampfer/?p=105

3

Из того, что я могу сказать, queen3 правильно, ваш DataContextAccessor класс должен реализовать IDisposable и вызвать datacontext.Dispose() из его метода .Dispose(). (Отказ от ответственности: Я не работал с замок Виндзор.)

Кроме того, что я хотел бы сделать, это превратить ваш DataContextAccessor в DataContextFactory, который создает только DataContext при вызове метода (например, GetContext()). Тогда вы можете сделать это:

using(DataContext context = myDataContextFactory.GetContext()) { 
    // Do whatever you want with the context 
} 
// Context is disposed here 

Вы также можете захотеть взглянуть на этот предыдущий вопрос: How do you reconcile IDisposable and IoC?

4

Нет Ваш DataContextAccessor не нужно реализовать IDisposable. Windsor достаточно умен, чтобы справиться с этим случаем, не внося никаких изменений в ваши классы.

Однако, поскольку в других ответах DataContext реализует его, и Виндзор видит его, и он регистрирует его для очистки (для вызова метода Dispose).

Что вам нужно сделать, это позвонить container.Release и передать ваш корневой сервис (который, вероятно, будет DataContextAccessor в вашем случае). Затем Windsor выпустит его и все его зависимости (он также будет звонить Dispose на DataContext), и память будет освобождена.

Если вы используете ASP.NET MVC, рассмотрите возможность использования проекта MVCContrib с интеграцией Windsor, которая обрабатывает выпуск компонентов для вас.

1

Я думаю, что @Krzysztof Koźmic прав ... вы должны освободить все, что вы получите от Виндзора.

Windsor довольно чуждо любому, кто привык к IDisposable. Причина этого очевидного несоответствия сводится к управлению жизненным циклом компонента.Если вы берете компонент Windsor, который является IDisposable, вы не знаете, настроен ли этот экземпляр как переходный или одноэлементный (и, конечно, это может измениться по мере развития вашего приложения).

Если вы разместите компонент, а потом окажется одиночным, некоторые другие клиентские коды будут задаваться вопросом, почему его компонент неожиданно вышел из строя!?! Только Windsor может принять решение об удалении.

Хороший блог Кшиштоф (не позволит мне размещать ссылку!)

В нашем приложении мы сделали все преходяще, кроме нескольких одиночек. Преходящая кажется самой простой моделью (пока все понимают, что вам нужно «Отпустить, а не уничтожать»). Если в ваших тестах есть фиктивный контейнер, вы можете установить, что Release вызывается для каждого компонента, который исправляет ваш макет, и я также слышал, что переходный процесс имеет меньше проблем с производительностью (??), чем в других режимах? Код, безусловно, более портативный.

Последнее, но не менее, если у вас есть утечка памяти, и вы должны работать, что и почему-то не собираются с помощью GC, проверьте потрясающую серию учебника Tess Ferrandez»на Windbg http://blogs.msdn.com/b/tess/archive/2008/04/03/net-debugging-demos-lab-7-memory-leak-review.aspx ... преступник может быть где-то неожиданным!

Смежные вопросы