Linq to SQL DataContext Windsor IoC проблема утечки памяти

У меня есть приложение ASP.NET MVC, которое создает текстовый текст Linq2SQL для каждого веб-запроса с использованием Castler Windsor IoC.

По какой-то причине, которую я не до конца понимаю, каждый раз, когда создается новый текстовый текст данных (при каждом веб-запросе), около 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; } }
 }

Webconfig Windsor IoC для создания этого экземпляра выглядит так:

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

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

4 ОТВЕТА

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 /? р = 105

6
10.11.2009 21:25:28

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

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

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

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

3
23.05.2017 11:48:18

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

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

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

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

4
18.05.2010 11:27:28

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

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

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

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

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

И последнее, но не менее важное: если у вас есть утечка памяти и вам нужно решить, что и почему что-то не собирается GC, посмотрите серию учебных пособий Тесс Феррандез на windbg http://blogs.msdn.com/b /tess/archive/2008/04/03/net-debugging-demos-lab-7-memory-leak-review.aspx ... виновник может быть где-то неожиданным!

1
13.10.2010 11:29:49