Hantera minnesanvändning i Windows App SDK skrivbordsappar

Effektiv minneshantering hjälper din app att fungera bra, särskilt på enheter med begränsade resurser. I den här artikeln beskrivs strategier för att hantera minne i en Windows App SDK skrivbordsapp, särskilt när appfönstret inte visas.

Important

Skrivbordsappar pausas inte automatiskt av systemet. De fortsätter att förbruka minne när de körs. Proaktiv minneshantering förbättrar systemets övergripande svarstider och batteritid.

Övervaka minnesanvändning

Använd Windows. System.MemoryManager-klassen för att kontrollera appens minnesförbrukning och det systemomfattande minnestillståndet:

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}");

Du kan också prenumerera på MemoryManager.AppMemoryUsageLimitChanging och MemoryManager.AppMemoryUsageIncreased för att svara på minnesbelastning.

Minska minnet när fönstret är dolt

Även om systemet inte pausar skrivbordsappen kan du minska minnesförbrukningen när fönstret minimeras eller döljs. Detta gör fler resurser tillgängliga för förgrundsappen och förlänger batteritiden.

Identifiera när fönstret är dolt

Microsoft.UI.Xaml.Window exponerar inte en VisibilityChanged-händelse. Använd Window.Activated i stället händelsen för att identifiera när ditt fönster förlorar fokus, eller använd AppWindow.Changed för att identifiera när den minimeras:

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();
    }
};

Vad du ska släppa

När fönstret är dolt bör du överväga att släppa:

  • Cachelagrade bilder och bitmappar – Ta bort stora bitmappar som bara behövs för visning.
  • Återgivningsmålresurser – Frigör GPU-resurser som används för återgivning.
  • Visa modelldata – Rensa samlingar eller cachelagrade data som kan läsas in igen när användaren returnerar.
  • Navigeringshistorik – Om din app har en navigeringsstack rensar du cachelagrade sidor.
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
}

Hantera systemminnestryck

Registrera dig för händelsen MemoryManager.AppMemoryUsageIncreased för att identifiera när systemets minnestryck ökar:

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();
    }
};

Tip

Även om skrivbordsappar inte avslutas automatiskt av systemet för att frigöra minne (till skillnad från UWP), håller en minskning av ditt fotavtryck under minnesbelastning systemet dynamiskt och undviker potentiella minnesbrister.

Metodtips

  • Frigör det du kan ladda om. Frigör endast resurser som du kan rekonstruera senare från disk, nätverk eller beräkning.
  • Minska gradvis. Börja med att släppa de största objekten först (bilder, cacheminnen, datasamlingar).
  • Testa på enheter med lite minne. Kontrollera att minneshanteringen fungerar på enheter med 4 GB eller mindre RAM-minne.
  • Undvik att hålla stora objekt i statiska fält. Använd lata inläsningsmönster i stället.