ASP.NET Core 6调用WCF服务时内存占用过高问题求助
问题:WCF相关对象无法被GC完全回收导致内存泄漏
背景
我有一个ASP.NET Core 6应用,会定时调用WCF服务获取数据,核心依赖注入配置如下:
builder.Services.AddSingleton<StorageCostDataService>(); builder.Services.AddSingleton<PeriodicDataSnapshotService>(); builder.Services.AddHostedService<PeriodicDataSnapshotService>(provider => provider.GetRequiredService<PeriodicDataSnapshotService>());
其中StorageCostDataService是WCF客户端,负责从服务端获取数据;PeriodicDataSnapshotService作为后台服务定时执行逻辑,定义如下:
public class PeriodicDataSnapshotService : BackgroundService { private PeriodicTimer? _periodicTimer; private readonly StorageCostDataService _storageCostDataService; public PeriodicDataSnapshotService(StorageCostDataService storageCostDataService) { _storageCostDataService = storageCostDataService; } protected override async Task ExecuteAsync(CancellationToken stoppingToken) { _periodicTimer = new PeriodicTimer(_period); while (await _periodicTimer.WaitForNextTickAsync(stoppingToken)) { try { using var storageStateViewerContext = new StorageStateViewerContext(); var storageCostOverviewData = _storageCostDataService.GetStorageCostOverviewData(2000); var storageCostOverviewRemainingValueHistoryData = _storageCostDataService.GetStorageCostOverviewRemainingValueData(2000); storageStateViewerContext.StorageOverviewHistories.Add(storageOverviewHistory); storageStateViewerContext.SaveChanges(); storageCostOverviewData = null; storageCostOverviewRemainingValueHistoryData = null; } catch (Exception ex) { _logger.LogError(ex.Message); } } throw new NotImplementedException(); } }
该服务从WCF获取数据后处理并存储到EF Core的DbContext中。调试时发现内存占用异常:启动初始约60MB,首次调用服务后增至260MB,之后每次定时执行都会新增200MB内存;GC触发后仅从3GB左右降至2GB,无法完全回收。内存快照显示,大量未被回收的死对象均来自StorageCostDataService。
WCF客户端核心实现如下:
public Dictionary<string, List<ErpBatchCostOverviewItem>> GetStorageCostOverviewData(int limit) { using (var svc = new ErpInterfaceWebserviceClient()) { var b = svc.Endpoint.Binding as BasicHttpBinding; if (b == null) { throw new Exception("Couldn't create service endpoint"); } b.MaxReceivedMessageSize = int.MaxValue; b.BypassProxyOnLocal = true; b.UseDefaultWebProxy = false; var endpoint = svc.Endpoint; endpoint.Address = new EndpointAddress("http://svr-el-sql.work.local:1035/ErpInterface"); svc.OpenAsync().Wait(); var serverData = svc.GetErpBatchCostOverview(); svc.Close(); var erpBatchCostOverviewItems = serverData .Where(d => d.GroupId != 71) .GroupBy(d => d.Ident) .OrderByDescending(d => d.Sum(e => e.Price * e.Amount)) .Take(limit) .ToDictionary(d => d.Key, d => d.ToList()) ; return erpBatchCostOverviewItems; } }
已按建议将DbContext包裹在using语句中,调整PeriodicTimer为局部字段,但内存问题未改善。Visual Studio诊断工具显示,GC分别在400MB、1.5GB、2.2GB时触发,回收后仍残留大量ErpInterfaceService相关对象。
疑问
为何这些WCF相关对象无法被GC完全回收?
内容的提问来源于stack exchange,提问作者Tom L.
相关产品推荐
相关产品推荐

