共用方式為


防止 Windows 應用程式中的記憶體流失

受影響的平臺

用戶端 - Windows 7
伺服器 - Windows Server 2008 R2

描述

記憶體洩漏是一種 Bug 類別,指當不再需要時,應用程式無法釋放記憶體。 經過一段時間,記憶體流失會影響特定應用程式與作系統的效能。 由於分頁過多,大規模洩漏可能會導致無法容忍的反應時間。 最終,應用程式以及作系統的其他部分將經歷失敗。

Windows 會在進程終止時釋放應用程式配置的所有記憶體,因此短期執行的應用程式不會影響整體系統效能。 不過,長時間執行的進程,例如服務或甚至是 Explorer 的外掛程式,可能會嚴重影響系統的可靠性,甚至可能強迫使用者重新啟動 Windows,使系統能再次使用。

應用程式可以透過多個方式代表其配置記憶體。 如果使用後未釋放,則每種分配類型都可能會導致洩漏。 以下是常見配置模式的一些範例:

  • 透過 HeapAlloc 函式或其 C/C++ 執行時間對等專案 malloc新的 堆積記憶體
  • 透過作業系統的 VirtualAlloc 函式直接配置。
  • 透過 Kernel32 API 建立的核心句柄,例如 CreateFileCreateEventCreateThread,代表應用程式保留核心記憶體
  • 透過 User32 和 Gdi32 API 建立的 GDI 和 USER 句柄(根據預設,每個進程都有 10,000 個句柄的配額)

最佳做法

監視應用程式一段時間的資源耗用量,是偵測和診斷記憶體流失的第一個步驟。 使用 Windows 任務管理員並新增下列數據行:「認可大小」、「句柄」、「用戶物件」和「GDI 物件」。 這可讓您建立應用程式的基準,並監視一段時間的資源使用量。

顯示 Windows 任務管理員中 [處理程式] 頁面的螢幕快照。

下列Microsoft工具提供更詳細的資訊,並有助於偵測和診斷應用程式中各種配置類型的洩漏:

  • 性能監視器和資源監視器是 Windows 7 的一部分,可監視和圖表一段時間的資源使用
  • 最新版本的 Application Verifier 可以診斷 Windows 7 上的記憶體堆積洩漏問題。
  • UMDH 是 Windows 偵錯工具的一部分,會分析指定進程的堆積記憶體配置,並有助於尋找流失和其他不尋常的使用模式
  • Xperf 是一種複雜的效能分析工具,可支援堆積配置追蹤
  • CRT 偵錯堆積會追蹤堆積配置,並可協助建置您自己的堆積偵錯功能

某些程式代碼撰寫和設計做法可以限制程式代碼中的流失次數。

  • 在C++程式碼中,使用智慧指標來管理堆記憶體分配以及 Win32 資源,如內核 HANDLE等。 C++ 標準函式庫提供用於堆記憶體配置的 auto_ptr 類別。 針對其他分配類型,您必須編寫自己的類別。 ATL 程式庫提供一組豐富的類別,可用於堆區物件和核心控制代碼的自動資源管理。
  • 使用編譯程式內建功能,例如 _com_ptr_t 將 COM 介面指標封裝成「智慧型指標」,並協助進行參考計數。 其他 COM 數據類型也有類似的類別:_bstr_t_variant_t
  • 監視 .NET 程式代碼不尋常的記憶體使用量。 受控代碼不免於記憶體洩漏。 要了解如何查找 GC 洩漏,請參閱 「查找受控記憶體洩漏」
  • 請注意 Web 用戶端程式代碼中的外洩模式。 COM 物件與腳本引擎(例如 JScript)之間的循環參考可能會導致網頁應用程式中發生大量記憶體洩漏。 「瞭解和解決 Internet Explorer 洩漏模式」 有這類洩漏的詳細資訊。 您可以使用 JavaScript 記憶體流失偵測器來偵錯程式代碼中的記憶體流失。 雖然隨附於 Windows 7 的 Windows Internet Explorer 8 可減輕這些問題的大部分問題,但較舊的瀏覽器仍然容易受到這些 Bug 的影響
  • 避免使用函式中的多個結束路徑。 指派給函式範圍變數的配置應該在函式結尾的一個特定區塊中釋放
  • 請勿在程序代碼中使用例外狀況,而不釋放函式中的所有局部變數。 如果您使用原生例外狀況,請在 __finally 區塊內釋放所有配置。 如果您使用 C++ 異常,所有的堆積和處理配置都必須包裝在智慧指標中。
  • 請勿捨棄或重新初始化 PROPVARIANT 物件,而不呼叫 PropVariantClear 函式

常見的配置模式:

Microsoft 工具:

其他連結: