我需要一个IHostedService,或“工作服务”,但我遇到了一个有趣的难题,那就是垃圾收集器不会在“适当的”时间运行。相反,它只是不收集任何资源,导致应用程序仅增加内存使用量(在调试期间,根本没有GC发生)。
我已经完成了所有可想到的事情,包括让我的所有任务都返回一些值,并在可能的情况下使用using语句。还使用依赖注入抽象几个层,(以确保有多个地方应该与运行时通信,以便运行垃圾收集。
我唯一的“解决方案”,不是解决方案,是手动运行GC.Collect();
namespace Worker
{
public class Worker : BackgroundService
{
private readonly ILogger<Worker> _logger;
public Worker(ILogger<Worker> logger)
{
_logger = logger;
}
protected override async Task ExecuteAsync(CancellationToken stoppingToken)
{
while (!stoppingToken.IsCancellationRequested)
{
_logger.LogInformation($"Worker running at: {DateTime.Now}");
var files = Directory.EnumerateFiles(@"C:\\repos\");
var date = files.Select(f => File.ReadAllBytesAsync(f));
GC.Collect();
}
}
}
}
结果是我的代码在没有手动触发GC的情况下会膨胀以最大化可用内存,但是,使用手动GC,这可以运行数小时而不会显着改变资源使用情况
这是服务器GC的预期行为。它经过调整以充分利用可用内存,因此除非确实需要,否则不会收集。这真的是问题吗?操作系统能够根据需要进出存储器,因此如果你以64位运行,它在大多数情况下都不会产生影响。如果这仍然是一个问题,有几个选择:
gcServer
setting设置为false
将激活工作站GCGCHeapCount
设置完成。有关更多信息,请参阅Maoni Stephens的this article.NET Core 3.0将带来新的设置来调整GC的低内存情况,但它不会在第二学期之前发布。