Contexto: Tenho uma instância do SQL Server em execução em uma de nossas VMs com 64 GB de memória. Atualmente, há um limite máximo de 60 GB e um limite mínimo de 0 GB. O SQL Server é o único aplicativo em execução no servidor que consome memória significativa.
Recentemente, lancei um recurso que faz consultas caras e repetidas ao SQL Server e, sempre que há muitos usuários usando o recurso, o uso de memória aumenta conforme o esperado. Não cheguei nem perto do limite, mas estou curioso para saber o que acontece quando nos aproximamos dele.
De acordo com a documentação da MS, li que o SQL Server manipula dinamicamente a memória para uso conforme necessário, mas não consegui encontrar nada sobre a lógica na qual o SQL Server libera memória dinamicamente.
Questões:
- Ele começa a liberar memória antes de atingir o limite especificado? O que (mais) aciona a liberação de memória?
- Como o SQL Server determina qual memória liberar? Ele libera memória de maneira FIFO?
Estou esquecendo completamente de algum ponto?
Isso se deve principalmente ao fato de que o uso de memória interna é um detalhe de implementação que pode (e muda) entre versões principais e até mesmo CUs. Isso sem mencionar o número de sinalizadores de rastreamento que podem alterar ainda mais os comportamentos.
Há dois botões que você já encontrou
MinServerMemory
eMaxServerMemory
que fazem o básico do que os administradores podem usar para afetar o comportamento geral no ambiente do sistema operacional (OSE). Fora isso, há sinalizadores de rastreamento, a maioria dos quais não estão disponíveis publicamente, que podem alterar comportamentos.O próximo item é controlado pelo administrador, que é a quantidade de memória e outros aplicativos que estão sendo executados no OSE. O SQL Server escuta o Windows, que pode definir uma Condição de Memória Baixa para o OSE para informar aos aplicativos que o computador está com pouca memória e os aplicativos podem (se eles assinarem o evento). O SQL Server age definindo diferentes sinalizadores internamente, o que faz com que os vários funcionários implementem uma rotina de pressão de memória externa - nem todos o fazem. Se eles implementaram isso, isso entrará em ação, se ajuda ou não, é uma incógnita. Ter seu antivírus ou qualquer software em ação e escanear tudo no sistema enquanto consome 20 GB de memória pode não ser bom se você já tiver definido a memória máxima do servidor muito alta.
Finalmente, há a pressão de memória interna que está entre diferentes usos de memória dentro do SQL Server. Alguns itens implementam uma rotina de pressão de memória interna , outros não, por exemplo, o gerenciador de bloqueio não cederá memória.
O último item controlável no nível do aplicativo (mais ou menos, de novo) é a carga de trabalho. Se não houver consultas ajustadas e tomando toneladas de bloqueios simultâneos, o gerenciador de bloqueios aumentará de tamanho e nunca devolverá isso. O ajuste do aplicativo (junto com o ajuste de consulta) pode e vai levá-lo longe, pois grandes concessões de memória são permitidas (dependendo da versão e CU) para ir além da memória máxima do servidor, o que pode causar a reação ruim da cadeia de eventos.
Se você quiser aprender mais sobre o gerenciamento de memória interna e externa do SQL Server, eu recomendo o livro SQL Server Internals . É de 2012, mas as partes principais dele ainda são aplicáveis.