O problema foi causado pelo aplicativo usando FILE_FLAG_RANDOM_ACCESS . Eu consertei o aplicativo.
Se alguém postar uma solução genérica, eu irei reatribuir a resposta correta à sua resposta.
O problema que estou enfrentando é bastante simples: enquanto a memória usada pelos aplicativos é muito pequena (~ 2GB), ao mesmo tempo o Gerenciador de tarefas relata que o servidor tem basicamente toda a memória em uso (16GB). Durante isso, começa a troca, o desempenho passa pelo chão e a latência passa pelo telhado.
Eu diagnostiquei isso de volta em um aplicativo que abre muitos arquivos usando o acesso à memória mapeada (provavelmente de uma maneira não muito padronizada, como está escrito no Delphi). RamMap da Sysinternals relata que esses 14GB são usados para "Arquivo Mapeado", no estado Ativo. A questão é que essa memória não é usada ativamente, esses aplicativos estão no modo de espera, sem clientes conectados. Tão ocioso quanto possível.
Para trazer o uso da memória de volta aos níveis normais, eu só preciso usar a opção "Empty → Empty System Working Set" no RamMap. Isso corrige o problema de não haver memória livre enquanto não houver nova atividade (leitura de arquivos de dados, etc.). Em seguida, o uso da memória aumenta e o desempenho diminui novamente.
A solução seria escrever um script para fazer a mesma coisa que o RamMap faz a cada poucos minutos. É onde estou preso. Eu encontrei a função EmptyWorkingSet
WinAPI e encontrei o script do PowerShell para executá-lo em todos os processos no sistema, mas ele reduz a memória usada em no máximo 200-300MB e não poucos GB que o RamMap é capaz.
Como executar a opção RamMap Empty System Working Set regularmente?
O problema foi causado pelo aplicativo usando FILE_FLAG_RANDOM_ACCESS . Eu consertei o aplicativo.
Se alguém postar uma solução genérica, eu irei reatribuir a resposta correta à sua resposta.