管理 Windows 應用程式 SDK 桌面應用程式中的記憶體使用情況

有效的記憶體管理有助於你的應用程式表現良好,尤其是在資源有限的裝置上。 本文說明了在 Windows 應用程式 SDK 桌面應用程式中管理記憶體的策略,特別是當你的應用程式視窗不可見時。

Important

桌面應用程式 不會自動被系統暫停 。 它們在運行時仍持續消耗記憶體。 主動式記憶體管理提升整體系統反應速度與電池續航力。

監視記憶體使用量

Windows。System.MemoryManager 類別用來檢查應用程式的記憶體消耗及系統整體記憶體狀態:

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

你也可以訂閱 MemoryManager.AppMemoryUsageLimitChangingMemoryManager.AppMemoryUsageIncrease ,以回應記憶體壓力。

當視窗被隱藏時,減少記憶體

雖然系統不會暫停桌面應用程式,但當視窗最小化或隱藏時,你可以減少記憶體消耗。 這讓前景應用程式能使用更多資源,並延長電池續航力。

偵測視窗是否隱藏

Microsoft.UI.Xaml.Window 不會公開 VisibilityChanged 事件。 相反地,請用事件 Window.Activated 來偵測視窗何時失去焦點,或用 AppWindow.Changed 來偵測視窗何時被最小化:

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

該發行什麼

當視窗被隱藏時,可以考慮釋放下列資源:

  • 快取圖片與點陣圖 — 丟棄僅用於顯示的大型點陣圖。
  • 渲染目標資源 — 釋放用於渲染的 GPU 資源。
  • 檢視模型資料 — 清除集合或快取資料,使用者回傳時可重新載入。
  • 導航歷史 — 如果你的應用程式有導覽堆疊,請清除快取頁面。
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
}

因應系統記憶體壓力

註冊 MemoryManager.AppMemoryUsageIncreased 事件,以偵測系統記憶體壓力上升:

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

雖然桌面應用程式不會像 UWP 那樣自動被系統終止以釋放記憶體,但在記憶體壓力下減少佔用空間能保持系統反應迅速,避免潛在的記憶體不足狀況。

最佳做法

  • 發布你可以重新載入的內容。 只釋放那些你之後可以從磁碟、網路或計算中重建的資源。
  • 慢慢減少。 先從釋出最大型的項目開始(圖片、快取、資料收集)。
  • 在記憶體較低的裝置上測試。 確認你的記憶體管理在記憶體容量不超過 4 GB 的裝置上正常運作。
  • 避免將大型物體置於靜態場中。 改用延遲載入模式。