依赖注入中使用Quartz调用方法引发内存暴涨问题
Quartz调用EF Core方法时内存暴涨问题
我在使用Quartz调用依赖EF Core的方法时出现异常:通过WebAPI每秒调用该方法无内存问题,但通过Quartz每秒调用时,堆内存会在数秒内急剧暴涨。
注:以下为简化原问题的演示项目代码:
Program.cs 依赖注入配置
builder.Services .AddSingleton<JobManager>() .AddTransient<Job>() .AddTransient<IMemoryLeakingService, MemoryLeakingService>() .AddTransient<IDbConnectionStringHelper, DbConnectionStringHelper>() .AddTransient<IJobFactory, JobFactory>() .AddTransient<ISchedulerFactory, StdSchedulerFactory>() .AddDbContext<IMyContext, MyContext>((provider, options) => { options.UseSqlite(provider.GetRequiredService<IDbConnectionStringHelper>().ConnectionString); options.EnableSensitiveDataLogging(); options.EnableDetailedErrors(); }, ServiceLifetime.Transient, ServiceLifetime.Transient) ;
JobManager(任务启动类)代码
public class JobManager { private readonly ILogger<JobManager> _logger; private readonly IJobFactory _jobFactory; private readonly ISchedulerFactory _schedulerFactory; private IScheduler _scheduler; public JobManager(ILogger<JobManager> logger, IJobFactory jobFactory, ISchedulerFactory schedulerFactory) { _logger = logger; _jobFactory = jobFactory; _schedulerFactory = schedulerFactory; } public async Task StartJobs() { _logger.LogTrace("{Method}()", nameof(StartJobs)); _scheduler = _schedulerFactory.GetScheduler().GetAwaiter().GetResult(); _scheduler.JobFactory = _jobFactory; var everySecondTrigger = TriggerBuilder.Create() .WithSchedule(SimpleScheduleBuilder.RepeatSecondlyForever(1)).Build(); var job = JobBuilder.Create<Job>().Build(); var triggersAndJobs = new Dictionary<IJobDetail, IReadOnlyCollection<ITrigger>> { {job, new HashSet<ITrigger> {everySecondTrigger}}, }; await _scheduler.ScheduleJobs(triggersAndJobs, false).ConfigureAwait(false); await _scheduler.Start().ConfigureAwait(false); } }
Job类代码
public class Job : IJob { private readonly ILogger<Job> _logger; private readonly IMemoryLeakingService _memoryLeakingService; public Job(ILogger<Job> logger, IMemoryLeakingService memoryLeakingService) { _logger = logger; _memoryLeakingService = memoryLeakingService; } public async Task Execute(IJobExecutionContext context) { _logger.LogTrace("{method}({context})", nameof(Execute), context); await _memoryLeakingService.ReadData(); } }
MemoryLeakingService及ReadData方法代码
public class MemoryLeakingService : IMemoryLeakingService { private readonly ILogger<MemoryLeakingService> _logger; private readonly IMyContext _context; private readonly List<string> _strings; public MemoryLeakingService(ILogger<MemoryLeakingService> logger, IMyContext context) { _logger = logger; _context = context; _strings = new List<string>(); var guid = Guid.NewGuid().ToString(); for (int i = 0; i < 1000; i++) { _strings.Add(guid); } } public async Task ReadData() { _logger.LogInformation("{method}() called", nameof(WriteData)); var demoEntities = await _context.DemoEntities.ToListAsync(); } }
内存诊断截图

前255秒通过WebAPI调用ReadData方法时堆内存正常;启动Quartz任务后,被引用对象数量瞬间剧增。为何两种调用方式存在差异?占用内存的对象是EF Core的变更跟踪对象,但不清楚Quartz调用时的差异原因。
内容的提问来源于stack exchange,提问作者Patrick
相关产品推荐
相关产品推荐

