# Uso de Memória CEF/Chromium em Aplicações de Longa Duração
IronPDF renderiza com o Chromium, por isso a memória do processo pode se manter alta por um curto período após a geração do PDF, mesmo quando os documentos são descartados e `GC.Collect()` é executado. Duas fontes estão em jogo: o alocador nativo não gerenciado do Chromium e o agrupamento de abas do navegador do IronPDF. Na maioria dos casos, isso é esperado e não significa automaticamente que há um vazamento de memória.
Isso se aplica ao IronPDF e `IronPdfEngine` no Windows e Linux, através de Docker, Kubernetes, VM e ambientes hospedados em servidores, e para .NET, Java e qualquer aplicação que use renderização baseada no Chromium.
## Por Que a Memória Permanece Elevada
Dois mecanismos distintos mantêm a memória alta após a conclusão de uma renderização.
**Retenção do alocador nativo do Chromium:** O Chromium usa uma grande quantidade de memória não gerenciada que vive fora do coletor de lixo do .NET. Quando uma renderização é concluída, o Chromium frequentemente mantém essa memória nativa reservada para reutilização em vez de devolvê-la ao sistema operacional imediatamente. Portanto, seus objetos `PdfDocument` podem ser descartados corretamente, o runtime pode coletar objetos gerenciados, e o processo ou container global ainda pode ler uma memória alta. Isso é normal para motores baseados no Chromium.
**Reuso de abas do BrowserPool:** O IronPDF pode manter abas do navegador ociosas ativas após uma renderização para que a próxima comece mais rápido. Essas abas mantêm seus subprocessos de renderizadores e estado de DOM por um curto período, criando um nível de memória visível, mesmo quando nada está sendo renderizado. Com o agrupamento ativado, você geralmente verá a memória aumentar durante a renderização, manter-se em um nível básico após a conclusão, e então cair em etapas à medida que as abas ociosas expiram e são removidas.
### Por Que `GC.Collect()` Não Ajuda
`GC.Collect()` apenas recupera memória gerenciada do .NET. Isso não força o Chromium a devolver memória nativa ao sistema operacional e não encerra as abas do BrowserPool que são intencionalmente mantidas vivas para reutilização. Mesmo com a eliminação correta e uma coleta forçada, os números mostrados pelo Gerenciador de Tarefas, Docker, Kubernetes ou ferramentas como New Relic podem não cair imediatamente.
O efeito é mais visível em aplicações de longa duração, ambientes de serviço compartilhados e implantações em Docker ou Kubernetes. Para integrações Java usando `IronPdfEngine`, a pressão geralmente aparece no processo do motor ou no container em vez do heap do JVM.
## Padrões do BrowserPool
O IronPDF mantém um pequeno número de abas aquecidas entre renderizações para melhorar o desempenho. Os padrões são:
- `BrowserPool.Enabled = true`
- `BrowserPool.MaxIdleTabs = min(max(ProcessorCount / 2, 1), 4)`
- `BrowserPool.IdleTimeoutSeconds = 30`
Por causa disso, mesmo sem renderizações ativas, o processo pode manter de 1 a 4 abas ociosas vivas brevemente, cada uma retendo memória nativa e recursos subprocesso até o tempo limite ocioso expirar. Dependendo do conteúdo renderizado e do ambiente, uma aba ociosa pode reter uma quantidade notável, cerca de 50 a 100 MB em algumas cargas de trabalho. Essa linha de base elevada pode persistir por cerca de 30 segundos após a última renderização antes de cair em etapas.
## Solução
Se o seu ambiente possui restrições de memória, as configurações do BrowserPool são a primeira coisa a ajustar. Os padrões são assim:
```csharp
renderer.RenderingOptions.BrowserPool.Enabled = true; // default
renderer.RenderingOptions.BrowserPool.MaxIdleTabs = 2; // default is CPU/2, clamped to 1-4
renderer.RenderingOptions.BrowserPool.IdleTimeoutSeconds = 30; // default
```
### Opção 1: Desabilitar Completamente o Agrupamento de Abas
Opte por isso quando você quiser a limpeza mais determinística após cada renderização.
```csharp
renderer.RenderingOptions.BrowserPool.Enabled = false;
```
### Opção 2: Mantenha o BrowserPool Ativado Sem Manter Abas Ociosas
Mantém o recurso ativado, mas evita manter abas aquecidas entre renderizações, dando uma limpeza determinística por renderização.
```csharp
renderer.RenderingOptions.BrowserPool.MaxIdleTabs = 0;
```
### Opção 3: Reduza o Tempo Ocioso
Um caminho do meio: mantenha algum benefício de reutilização, mas permita que a memória caia mais cedo após um tráfego intenso.
```csharp
renderer.RenderingOptions.BrowserPool.IdleTimeoutSeconds = 10;
```
**Escolhendo entre elas:**
- **`Enabled = false`:** a estabilidade da memória importa mais do que o desempenho de inicialização rápida.
- **`MaxIdleTabs = 0`:** você quer uma limpeza determinística por renderização sem desativar totalmente o recurso.
- **Reduza `IdleTimeoutSeconds`:** sua carga de trabalho chega em rajadas e você quer que a memória seja recuperada mais cedo após cada uma.
## Estratégias para Aplicações de Longa Duração
Se a sua aplicação deve manter a memória consistentemente baixa, trabalhe com estas estratégias na ordem, começando com o ajuste do BrowserPool antes de recorrer à reciclagem de processo.
### 1. Limite a Renderização Concorrente
Várias tarefas de renderização do Chromium executando ao mesmo tempo aumentam a pressão na memória nativa acentuadamente. Se você renderizar em paralelo, limite quantas execuções são feitas simultaneamente com um semáforo:
```csharp
private static readonly SemaphoreSlim RenderSemaphore = new(2);
public async Task<t> RunRenderAsync<t>(Func<t> renderWork)
{
await RenderSemaphore.WaitAsync();
try
{
return renderWork();
}
finally
{
RenderSemaphore.Release();
}
}
```
Envolva a chamada de renderização do IronPDF dentro da seção controlada para que apenas um número fixo de tarefas sejam executadas ao mesmo tempo.
### 2. Ajuste ou Desative o BrowserPool
Para muitas implantações sensíveis à memória, este é o primeiro passo mais eficaz. Desative completamente o BrowserPool, defina `MaxIdleTabs = 0` ou reduza `IdleTimeoutSeconds` para cargas de trabalho repentinas. Qualquer uma dessas opções pode reduzir a linha de base persistente pós-renderização sem uma estratégia de reinicialização completa.
### 3. Isole a Renderização em um Trabalhador Separado
Mover a renderização de PDF para fora da aplicação principal é um padrão forte para sistemas de produção. O aplicativo principal permanece estável, o trabalhador de renderização pode ser reiniciado sozinho, e a memória nativa do Chromium é totalmente liberada quando esse trabalhador é fechado. Antes de confiar na reciclagem, confirme se desabilitar o BrowserPool ou definir `MaxIdleTabs = 0` já lhe dá uma limpeza pré-determinada por renderização. A abordagem de isolamento compensa mais em ambientes Docker ou Kubernetes, sistemas de trabalhos em segundo plano e plataformas de API que precisam de isolamento de memória mais rigoroso.
### 4. Recicle o Trabalhador Apenas Quando Necessário
Onde há um teto rígido de memória e o ajuste do BrowserPool ainda está aquém, recicle o processo de renderização ou o container do trabalhador após um número determinado de tarefas. Pode significar reiniciar um trabalhador dedicado após um tamanho fixo de lote, girar containers de motores no Kubernetes ou isolar a renderização em um serviço que possa reiniciar independentemente. Considere isso como uma etapa posterior, não seu primeiro movimento.
## Quando Pode Ser um Vazamento
Memória elevada após a renderização não significa automaticamente um vazamento. A renderização baseada no Chromium tem dois tipos de reutilização a serem compreendidos: **reutilização no nível do alocador**, onde o Chromium reserva internamente páginas de memória nativas (normal, não diretamente controlável), e **reutilização no nível da aba**, onde o BrowserPool mantém abas inteiras vivas entre as renderizações (configurável, e frequentemente o maior contribuidor do que você vê nas ferramentas de monitoramento).
O padrão é normalmente esperado quando a memória sobe durante a renderização, estabiliza em vez de crescer sem limite, permanece elevada brevemente em seguida e depois cai enquanto as abas ociosas expiram ou permanece disponível para a próxima renderização.
Investigue mais a fundo quando:
- a memória continua aumentando sem estabilizar sob uma carga de trabalho semelhante
- a memória continua crescendo mesmo após reduzir a concorrência
- a memória continua crescendo mesmo após desabilitar o BrowserPool ou definir `MaxIdleTabs = 0`
- uma reprodução mínima mostra o mesmo padrão ao longo do tempo com entrada controlada
## Quando Contatar o Suporte
Entre em contato com o [suporte técnico](/troubleshooting/engineering-support-for-ironpdf/) se você conseguir reproduzir todos os seguintes:
1. memória continua crescendo sem estabilizar sob uma carga de trabalho controlada
2. o problema persiste após limitar a concorrência
3. o problema persiste após desabilitar o BrowserPool ou definir `MaxIdleTabs = 0`
4. você pode reproduzi-lo com um projeto de amostra mínima
Ao abrir um tíquete, inclua sua versão do IronPDF, sistema operacional e ambiente de hospedagem, detalhes do Docker ou Kubernetes, se aplicável, linguagem de programação, frequência de renderização e nível de concorrência, gráficos de memória ou capturas de tela de monitoramento e um exemplo de amostra mínima reproduzível.
IronPDF renderiza com o Chromium, por isso a memória do processo pode se manter alta por um curto período após a geração do PDF, mesmo quando os documentos são descartados e GC.Collect() é executado. Duas fontes estão em jogo: o alocador nativo não gerenciado do Chromium e o agrupamento de abas do navegador do IronPDF. Na maioria dos casos, isso é esperado e não significa automaticamente que há um vazamento de memória.
Isso se aplica ao IronPDF e IronPdfEngine no Windows e Linux, através de Docker, Kubernetes, VM e ambientes hospedados em servidores, e para .NET, Java e qualquer aplicação que use renderização baseada no Chromium.
Por Que a Memória Permanece Elevada
Dois mecanismos distintos mantêm a memória alta após a conclusão de uma renderização.
Retenção do alocador nativo do Chromium: O Chromium usa uma grande quantidade de memória não gerenciada que vive fora do coletor de lixo do .NET. Quando uma renderização é concluída, o Chromium frequentemente mantém essa memória nativa reservada para reutilização em vez de devolvê-la ao sistema operacional imediatamente. Portanto, seus objetos PdfDocument podem ser descartados corretamente, o runtime pode coletar objetos gerenciados, e o processo ou container global ainda pode ler uma memória alta. Isso é normal para motores baseados no Chromium.
Reuso de abas do BrowserPool: O IronPDF pode manter abas do navegador ociosas ativas após uma renderização para que a próxima comece mais rápido. Essas abas mantêm seus subprocessos de renderizadores e estado de DOM por um curto período, criando um nível de memória visível, mesmo quando nada está sendo renderizado. Com o agrupamento ativado, você geralmente verá a memória aumentar durante a renderização, manter-se em um nível básico após a conclusão, e então cair em etapas à medida que as abas ociosas expiram e são removidas.
Por Que GC.Collect() Não Ajuda
GC.Collect() apenas recupera memória gerenciada do .NET. Isso não força o Chromium a devolver memória nativa ao sistema operacional e não encerra as abas do BrowserPool que são intencionalmente mantidas vivas para reutilização. Mesmo com a eliminação correta e uma coleta forçada, os números mostrados pelo Gerenciador de Tarefas, Docker, Kubernetes ou ferramentas como New Relic podem não cair imediatamente.
O efeito é mais visível em aplicações de longa duração, ambientes de serviço compartilhados e implantações em Docker ou Kubernetes. Para integrações Java usando IronPdfEngine, a pressão geralmente aparece no processo do motor ou no container em vez do heap do JVM.
Padrões do BrowserPool
O IronPDF mantém um pequeno número de abas aquecidas entre renderizações para melhorar o desempenho. Os padrões são:
Por causa disso, mesmo sem renderizações ativas, o processo pode manter de 1 a 4 abas ociosas vivas brevemente, cada uma retendo memória nativa e recursos subprocesso até o tempo limite ocioso expirar. Dependendo do conteúdo renderizado e do ambiente, uma aba ociosa pode reter uma quantidade notável, cerca de 50 a 100 MB em algumas cargas de trabalho. Essa linha de base elevada pode persistir por cerca de 30 segundos após a última renderização antes de cair em etapas.
Solução
Se o seu ambiente possui restrições de memória, as configurações do BrowserPool são a primeira coisa a ajustar. Os padrões são assim:
renderer.RenderingOptions.BrowserPool.Enabled = true; // defaultrenderer.RenderingOptions.BrowserPool.MaxIdleTabs = 2; // default is CPU/2, clamped to 1-4renderer.RenderingOptions.BrowserPool.IdleTimeoutSeconds = 30; // default
renderer.RenderingOptions.BrowserPool.Enabled = true; // default
renderer.RenderingOptions.BrowserPool.MaxIdleTabs = 2; // default is CPU/2, clamped to 1-4
renderer.RenderingOptions.BrowserPool.IdleTimeoutSeconds = 30; // default
C#
Opção 1: Desabilitar Completamente o Agrupamento de Abas
Opte por isso quando você quiser a limpeza mais determinística após cada renderização.
Enabled = false: a estabilidade da memória importa mais do que o desempenho de inicialização rápida.
MaxIdleTabs = 0: você quer uma limpeza determinística por renderização sem desativar totalmente o recurso.
Reduza IdleTimeoutSeconds: sua carga de trabalho chega em rajadas e você quer que a memória seja recuperada mais cedo após cada uma.
Estratégias para Aplicações de Longa Duração
Se a sua aplicação deve manter a memória consistentemente baixa, trabalhe com estas estratégias na ordem, começando com o ajuste do BrowserPool antes de recorrer à reciclagem de processo.
1. Limite a Renderização Concorrente
Várias tarefas de renderização do Chromium executando ao mesmo tempo aumentam a pressão na memória nativa acentuadamente. Se você renderizar em paralelo, limite quantas execuções são feitas simultaneamente com um semáforo:
Envolva a chamada de renderização do IronPDF dentro da seção controlada para que apenas um número fixo de tarefas sejam executadas ao mesmo tempo.
2. Ajuste ou Desative o BrowserPool
Para muitas implantações sensíveis à memória, este é o primeiro passo mais eficaz. Desative completamente o BrowserPool, defina MaxIdleTabs = 0 ou reduza IdleTimeoutSeconds para cargas de trabalho repentinas. Qualquer uma dessas opções pode reduzir a linha de base persistente pós-renderização sem uma estratégia de reinicialização completa.
3. Isole a Renderização em um Trabalhador Separado
Mover a renderização de PDF para fora da aplicação principal é um padrão forte para sistemas de produção. O aplicativo principal permanece estável, o trabalhador de renderização pode ser reiniciado sozinho, e a memória nativa do Chromium é totalmente liberada quando esse trabalhador é fechado. Antes de confiar na reciclagem, confirme se desabilitar o BrowserPool ou definir MaxIdleTabs = 0 já lhe dá uma limpeza pré-determinada por renderização. A abordagem de isolamento compensa mais em ambientes Docker ou Kubernetes, sistemas de trabalhos em segundo plano e plataformas de API que precisam de isolamento de memória mais rigoroso.
4. Recicle o Trabalhador Apenas Quando Necessário
Onde há um teto rígido de memória e o ajuste do BrowserPool ainda está aquém, recicle o processo de renderização ou o container do trabalhador após um número determinado de tarefas. Pode significar reiniciar um trabalhador dedicado após um tamanho fixo de lote, girar containers de motores no Kubernetes ou isolar a renderização em um serviço que possa reiniciar independentemente. Considere isso como uma etapa posterior, não seu primeiro movimento.
Quando Pode Ser um Vazamento
Memória elevada após a renderização não significa automaticamente um vazamento. A renderização baseada no Chromium tem dois tipos de reutilização a serem compreendidos: reutilização no nível do alocador, onde o Chromium reserva internamente páginas de memória nativas (normal, não diretamente controlável), e reutilização no nível da aba, onde o BrowserPool mantém abas inteiras vivas entre as renderizações (configurável, e frequentemente o maior contribuidor do que você vê nas ferramentas de monitoramento).
O padrão é normalmente esperado quando a memória sobe durante a renderização, estabiliza em vez de crescer sem limite, permanece elevada brevemente em seguida e depois cai enquanto as abas ociosas expiram ou permanece disponível para a próxima renderização.
Investigue mais a fundo quando:
a memória continua aumentando sem estabilizar sob uma carga de trabalho semelhante
a memória continua crescendo mesmo após reduzir a concorrência
a memória continua crescendo mesmo após desabilitar o BrowserPool ou definir MaxIdleTabs = 0
uma reprodução mínima mostra o mesmo padrão ao longo do tempo com entrada controlada
Quando Contatar o Suporte
Entre em contato com o suporte técnico se você conseguir reproduzir todos os seguintes:
memória continua crescendo sem estabilizar sob uma carga de trabalho controlada
o problema persiste após limitar a concorrência
o problema persiste após desabilitar o BrowserPool ou definir MaxIdleTabs = 0
você pode reproduzi-lo com um projeto de amostra mínima
Ao abrir um tíquete, inclua sua versão do IronPDF, sistema operacional e ambiente de hospedagem, detalhes do Docker ou Kubernetes, se aplicável, linguagem de programação, frequência de renderização e nível de concorrência, gráficos de memória ou capturas de tela de monitoramento e um exemplo de amostra mínima reproduzível.
Curtis Chau é bacharel em Ciência da Computação (Universidade Carleton) e se especializa em desenvolvimento front-end, com experiência em Node.js, TypeScript, JavaScript e React. Apaixonado por criar interfaces de usuário intuitivas e esteticamente agradáveis, Curtis gosta de trabalhar com frameworks modernos e criar manuais bem estruturados e visualmente atraentes.