Resposta rápida: Experimente alterar a plataforma nas configurações da App Service para 64 Bit. Se estiver no modo 32 Bit a aplicação terá um limite de 2GB de uso de RAM.
App Services Windows são criadas por padrão em 32 Bit, já as Linux são todas 64 Bit.
A informação sobre o limite pode ser encontrada na documentação oficial da Microsoft.
Passei por esse problema recentemente em um projeto que está feito em ASP.NET(.NET5) e hospedado em uma App Service Azure Windows.
Por 2 meses consecutivos houve um período de 2 a 3 dias do mes em que a aplicação ficou lenta e disparando erros de memória intermitentes, isso coincidia com um aumento de acessos a aplicação.
Ao olhar o consumo de memória no Azure, foi observado que o uso de memória do Plano de Aplicativo nunca ultrapassava os 40% da capacidade total, a partir dessa informação fui caçar o motivo na Internet.
A aplicação foi atualizada para a plataforma 64 bit, mas para validar a solução antes que ocorresse um novo momento de pico, resolvi criar uma aplicação onde eu pudesse simular este estouro de memória.
Para isso criei uma aplicação ASP.NET de WebApis contendo uma API que aloca 1GB cada vez que é chamada:
using Microsoft.AspNetCore.Mvc;
using System;
using System.Collections.Generic;
namespace Teste.Controllers
{
[ApiController]
[Route("[controller]")]
public class EstouroDeMemoriaController : ControllerBase
{
static List<byte[]> list = new();
[HttpPost]
public void Adiciona1Gb()
{
var rnd = new Random();
long _1gb = (long)1e9;
var bytes = new byte[_1gb];
bytes[rnd.Next(0, bytes.Length)] = byte.MaxValue;
list.Add(bytes);
}
}
}
Publiquei esta aplicação em uma App Service Windows com capacidade de 7GB deixando o Swagger exposto para facilitar o teste.
Ao chamar a API 2 vezes, tudo OK!
A partir da 3ª chamada, começou a vir erro 500.
Era o esperado, as duas primeiras chamadas alocaram 2GB, e esta nova iria alocar mais 1GB estrapolando o limite suportado na plataforma 32 Bit.
Repeti o mesmo procedimento acima, mas agora ajustando a App Service para a plataforma 64 Bit.
As primeiras 5 chamadas ocorreram com sucesso, ocorrendo erro a partir da 6ª chamada. A aplicação conseguiu usar uma parcela bem maior da memória disponível na App Service, validando a solução.
Durante os testes utilizei o Kudu para acompanhar o uso de memória, na aba “Process explorer”.
O Kudu pode ser acessado através da opção “Ferramentas Avançadas” da App Service.
Ficou assim após as 5 chamadas:
É possível acompanhar o uso também através do menu “Métricas” da App Service, selecionando a métrica Private Bytes.