У меня есть приложение C#, которое запускает несколько потоков, которые выглядят следующим образом.
public void Update()
{
long UpdateInterval = 50;
while (_running)
{
long start = TimeMgr.Milliseconds();
if (start - _updateFinished > 200)
_logger.Warn("waking up from sleep too long - took {Time} ms. Thread ID: {Thread}", (start - _updateFinished), _threadId);
UpdateLogic();
_updateFinished = TimeMgr.Milliseconds();
long elapsed = _updateFinished - start;
if (elapsed < UpdateInterval)
Thread.Sleep((int)(UpdateInterval - elapsed));
else
{
if (elapsed > 200)
_logger.Warn("update took too long. {Time}ms. Thread ID: {Thread}", elapsed, _threadId);
}
}
}
Однако после 24 ч + запуска сообщение «просыпаться из спящего слишком долго» начинает срабатывать, показывая, что Это занимает 300 мс, для большинства потоков каждые 5-10 секунд. Я предположил, что это может быть сборщик мусора, поэтому мы переключились на gcServer = true
, после чего приложение использует больше памяти, однако все еще доступно <40%, прежде чем эта проблема снова запустится через ~ 24 часа. </p>
Запуск показов dotTrace что приложение проводит большую часть времени в спящем режиме, что следует ожидать при низкой нагрузке.
https://i.imgur.com/KG7RjJj.png
Ранее эта проблема работала на Windows 10 с использованием gcServer = true
, когда приложение набирало до 95% использования оперативной памяти, мы переключились на gcServer = false
, что, похоже, решило проблему.
Однако после перехода на наш новый компьютер с Windows Sever 2019 В общем, эта проблема, похоже, снова обострилась, и изменение этого значения, похоже, не имеет никакого эффекта, иначе задержка этого эффекта с 20% использования памяти до 30% использования памяти.
Наши текущие настройки app.config установлены на
<?xml version="1.0"?>
<configuration>
<runtime>
<gcServer enabled="true"/>
<gcConcurrent enabled="true"/>
</runtime>
<startup><supportedRuntime version="v4.0" sku=".NETFramework,Version=v4.8"/></startup></configuration>
и мы изначально устанавливаем это при запуске приложения
GCSettings.LatencyMode = GCLatencyMode.SustainedLowLatency;
В идеале мы бы хотели, чтобы сборка мусора занимала минимум количество времени возможно. На сервере выделено 64 ГБ памяти, и я рад, что этим приложением можно воспользоваться. Мы обычно делаем обновления для этого приложения 1 или 2 раза в неделю, поэтому в идеале мы хотели бы, чтобы 1 неделя работоспособности (которую мы могли бы достичь на нашей Windows 10 машине)
Вся помощь приветствуется
Редактировать: добавлен код TimeMgr.Milliseconds ()
private static readonly DateTime EpochDateTime = new DateTime(1970, 1, 1);
public static long Milliseconds()
{
return (long)(DateTime.UtcNow - EpochDateTime).TotalMilliseconds;
}
``