Gerenciar o uso de memória em aplicativos da área de trabalho SDK do Aplicativo Windows

O gerenciamento eficiente de memória ajuda seu aplicativo a ter um bom desempenho, especialmente em dispositivos com recursos limitados. Este artigo descreve estratégias para gerenciar a memória em um aplicativo da área de trabalho SDK do Aplicativo Windows, especialmente quando a janela do aplicativo não está visível.

Importante

Os aplicativos da área de trabalho não são suspensos automaticamente pelo sistema. Eles continuam consumindo memória durante a execução. O gerenciamento proativo de memória melhora a capacidade de resposta geral do sistema e a duração da bateria.

Monitorar o uso de memória

Use o Windows. Classe System.MemoryManager para verificar o consumo de memória do aplicativo e o estado de memória em todo o sistema:

ulong appMemoryUsage = Windows.System.MemoryManager.AppMemoryUsage;
ulong appMemoryLimit = Windows.System.MemoryManager.AppMemoryUsageLimit;
Windows.System.AppMemoryUsageLevel level = Windows.System.MemoryManager.AppMemoryUsageLevel;

System.Diagnostics.Debug.WriteLine(
    $"Memory: {appMemoryUsage / 1024 / 1024} MB used, " +
    $"limit: {appMemoryLimit / 1024 / 1024} MB, level: {level}");

Você também pode assinar MemoryManager.AppMemoryUsageLimitChanging e MemoryManager.AppMemoryUsageIncreased para responder à pressão de memória.

Reduzir a memória quando a janela estiver oculta

Embora o sistema não suspenda seu aplicativo da área de trabalho, você pode reduzir o consumo de memória quando sua janela é minimizada ou oculta. Isso disponibiliza mais recursos para o aplicativo em primeiro plano e estende a vida útil da bateria.

Detectar quando a janela está oculta

Microsoft.UI.Xaml.Window não expõe um evento VisibilityChanged. Em vez disso, use o evento Window.Activated para detectar quando sua janela perder o foco ou use AppWindow.Changed para detectar quando for minimizada:

var m_window = App_Window;

void ReduceMemoryUsage() { }
void RestoreResources() { }

m_window.Activated += (sender, args) =>
{
    if (args.WindowActivationState == WindowActivationState.Deactivated)
    {
        // Window lost focus — consider reducing memory usage
        ReduceMemoryUsage();
    }
    else
    {
        // Window is active — reload resources
        RestoreResources();
    }
};

// To specifically detect minimize, use AppWindow.Changed
var appWindow = m_window.AppWindow;
appWindow.Changed += (sender, args) =>
{
    if (args.DidPresenterChange &&
        sender.Presenter is OverlappedPresenter presenter &&
        presenter.State == OverlappedPresenterState.Minimized)
    {
        // Window is minimized — reduce memory usage
        ReduceMemoryUsage();
    }
};

O que publicar

Quando a janela estiver oculta, considere liberar:

  • Imagens armazenadas em cache e bitmaps — Descartar bitmaps grandes que são necessários somente para exibição.
  • Recursos de destino de renderização – liberar recursos de GPU usados para renderização.
  • Dados do modelo de exibição – limpar coleções ou dados armazenados em cache que podem ser recarregados quando o usuário retorna.
  • Histórico de navegação — se o aplicativo tiver uma pilha de navegação, limpe as páginas armazenadas em cache.
private System.Collections.Generic.List<object>? _imageCache;
private global::Microsoft.UI.Xaml.Window m_window = App_Window;

private void ReduceMemoryUsage()
{
    // Release cached images
    _imageCache?.Clear();

    // Clear navigation cache
    if (m_window.Content is Frame rootFrame)
    {
        rootFrame.CacheSize = 0;
    }

    // Hint the GC to collect if appropriate, without forcing a blocking collection.
    // Only call this in response to system memory pressure, not on every hide.
    GC.Collect(2, GCCollectionMode.Optimized, blocking: false);
}

private void RestoreResources()
{
    // Restore navigation cache
    if (m_window.Content is Frame rootFrame)
    {
        rootFrame.CacheSize = 10;
    }

    // Reload other resources as needed
}

Gerenciar a pressão na memória do sistema

Registre-se no evento MemoryManager.AppMemoryUsageIncreased para detectar quando a pressão de memória do sistema aumenta:

void ReduceMemoryUsage() { }

Windows.System.MemoryManager.AppMemoryUsageIncreased += (sender, e) =>
{
    var level = Windows.System.MemoryManager.AppMemoryUsageLevel;

    if (level == Windows.System.AppMemoryUsageLevel.OverLimit ||
        level == Windows.System.AppMemoryUsageLevel.High)
    {
        ReduceMemoryUsage();
    }
};

Dica

Embora os aplicativos da área de trabalho não sejam encerrados automaticamente pelo sistema para liberar memória (ao contrário dos aplicativos UWP), reduzir o consumo de memória quando o sistema está sob pressão de memória mantém o sistema responsivo e evita possíveis condições de falta de memória.

Práticas recomendadas

  • Descarregue o que você pode recarregar. Libere apenas os recursos que você pode reconstruir posteriormente do disco, da rede ou da computação.
  • Reduza gradualmente. Comece liberando primeiro os maiores itens (imagens, caches, coletas de dados).
  • Teste em dispositivos de memória baixa. Verifique se o gerenciamento de memória funciona em dispositivos com 4 GB ou menos de RAM.
  • Evite manter objetos grandes em campos estáticos. Em vez disso, use padrões de carregamento lentos.