Веб-Api OData версии 4.0 и использование памяти / утечка с Castle Windsor

#entity-framework #memory-leaks #asp.net-web-api2 #odata #castle-windsor

#entity-framework #утечки памяти #asp.net-web-api2 #odata #castle-windsor

Вопрос:

У меня есть веб-проект, который настроен на предоставление конечной точки OData версии 4.0 и использует следующие компоненты:

  • ASP.NET Веб-Api 5.2.2
  • Entity Framework 6.1.1
  • Owin 5.2.2
  • OData 5.3.1

Все веб-приложение использует Windsor container из Castle Project. Образ жизни моих контроллеров зависит от веб-запроса, и то же самое относится ко всем зависимостям, включая DbContext.

IoC настроен следующим образом:

Owin Startup .cs

 WindsorConfig.InitializeContainer(GlobalConfiguration.Configuration);
  

Configuration.cs

 IWindsorContainer container = new WindsorContainer();
container.Install(FromAssembly.This());
container.Register(Component.For<IWindsorContainer>().Instance(container));
config.DependencyResolver = new WindsorDependencyResolver(container);
  

Installer.cs

 container.Register(FromAssembly.This()
    .BasedOn<ODataController>()
    .LifestylePerWebRequest());
container.Register(
    Component
    .For<DbContext>()
    .ImplementedBy<MyContext>()
    .LifestylePerWebRequest());
  

Итак, контроллер OData выглядит следующим образом:

 public class PersonsController : ODataController
{
    #region Public Constructors

    public PersonsController(ICommandDispatcher commandDispatcher, DbContext session)
    {
        this.commandDispatcher = commandDispatcher;
        this.session = session;
    }

    public IQueryable<Person> Get()
    {
        return session
            .Set<Person>()
            .AsNoTracking();
    }

    public SingleResult<Person> Get([FromODataUri] Guid key)
    {
        return SingleResult.Create(session
            .Set<Person>()
            .AsNoTracking()
            .Where(x => x.Id == key));
    }

}
  

Я использую Set.AsNoTracking(), чтобы избежать дополнительного использования памяти Entity Framework.
В любом случае, со временем после 100/150 запросов память пула приложений продолжает увеличиваться на 1-2 МБ, и она никогда не перерабатывается.

Я делаю что-то не так? Может быть, Castle не подходит для этого проекта, и я должен использовать другой контейнер IoC?

Комментарии:

1. Вы пробовали длительное нагрузочное тестирование? 10000 запросов и более. Что происходит тогда?

2. Честно говоря, нет, я создам нагрузочный тест и запущу его сегодня днем. Проблема в том, что используемая память никогда не освобождается. Например, приложение запускается с 5 МБ, после некоторого запуска оно увеличивается до 171 МБ, но никогда не возвращается к 5 МБ, даже если оно неактивно в течение дня или около того

3. Освобождается ли он, если вы вызываете GC. Собирать? Я блуждаю только в том случае, запущен GC или нет. Если GC запускается и память не восстанавливается — тогда это утечка памяти. Я протестирую ваш код и поэкспериментирую.

4. Это веб-приложение, как мне вызвать GC. Собирать? Я не могу, это стек веб-api, который вызывает его, когда контроллер возвращает результат. Вот почему я использую стиль жизни Castle Windsor. PerWebRequest

5. Вы видели заметки web.config здесь: github.com/castleproject/Windsor/blob/master/docs /…