Утечка памяти: что именно происходит за кулисами? - PullRequest
0 голосов
/ 22 января 2019

У меня есть приложение, которое часто останавливается из-за утечек памяти.

ContainerFactory class

public class ContainerFactory: IContainerFactory
{
    public TTypeOfInstance GetInstance<TTypeOfInstance>()
    {
        return _container.Resolve<TTypeOfInstance>();
    }
    public TTypeOfInstance GetLoggerInstance<TTypeOfInstance>()
    {
        using (var lifetimeScope = _container.BeginLifetimeScope())
        {
            return lifetimeScope.Resolve<TTypeOfInstance>();
        }
    }

    public void ScopedInstance<TTypeOfInstance>(Action<TTypeOfInstance> method)
    {
        using (var scopedInstance = _container.BeginLifetimeScope())
        {
            var instance = scopedInstance.Resolve<TTypeOfInstance>();
            method(instance);
        }
    }
  }

Я создаю экземпляр моего logger в конструкторе, как показано ниже, и вызывает memory leak, и мое приложение завершается сбоем каждый дополнительный день

    public MyClass(IContainerFactory containerFactory)
    {
        _containerFactory = containerFactory;
        _logger = _containerFactory.GetInstance<ILogger>().ForContext(GetType());
    }

Не будет никакой утечки памяти, если я изменю свой код следующим образом

  logger = containerFactory.GetLoggerInstance<ILogger>().ForContext(GetType()); 

Итак, что именно BeginLifetimeScope делает и как это помогает убить памятьпроблема?

И, это правильный способ создания экземпляра?Есть ли лучший способ?

Вот утечка памяти

enter image description here

Это исключение

Версия Framework: v4.0.30319 Описание: процесс был прерван из-за необработанного исключения.Информация об исключении: System.AccessViolationException в Serilog.Events.DictionaryValue..ctor (System.Collections.Generic.IEnumerable1>) в Serilog.Capturing.PropertyValueConverter.TryConvertEnumerable (System.Object, Serilog.Parsing.Destructure.Events.LogEventPropertyValue ByRef) at Serilog.Capturing.PropertyValueConverter.CreatePropertyValue(System.Object, Serilog.Parsing.Destructuring, Int32) at Serilog.Capturing.MessageTemplateProcessor.CreateProperty(System.String, System.Object, Boolean) at serilog.Exceptions.Destructurers.ExceptionEnricher.Enrich(Serilog.Events.LogEvent, Serilog.Core.ILogEventPropertyFactory)

Так настроен регистратор

    public static IContainerFactory BuildContainer()
    {
        var containerFactory = new ContainerFactory();
        var appSettings = ConfigurationManager.AppSettings;
        var applicationName = appSettings.Get("applicationName");
         builder.RegisterInstance(containerFactory).As<IContainerFactory>();
        builder.Register(c => GetLoggerConfiguration(applicationName).CreateLogger()).As<ILogger>();
    }


    private static LoggerConfiguration GetLoggerConfiguration(string applicationName)
    {
        var config = new LoggerConfiguration();
        if (!string.IsNullOrWhiteSpace(Settings.Default.ApplicationInsightsInstrumentationKey))
        {
            config = config.WriteTo.ApplicationInsightsEvents(Settings.Default.ApplicationInsightsInstrumentationKey, LogEventLevel.Error);
        }

        config = config.
            Enrich.WithProperty("ApplicationName", applicationName).
            Enrich.WithExceptionDetails().
            Enrich.WithMachineName().
            Enrich.WithProcessId().
            Enrich.WithThreadId().
            ReadFrom.AppSettings();

        return config;
    }
...