У меня есть приложение, которое часто останавливается из-за утечек памяти.
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
делает и как это помогает убить памятьпроблема?
И, это правильный способ создания экземпляра?Есть ли лучший способ?
Вот утечка памяти
Это исключение
Версия 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;
}