Verhindern von Speicherlecks in Windows Anwendungen

Betroffene Plattformen

Clients – Windows 7
Server – Windows Server 2008 R2

BESCHREIBUNG

Speicherlecks sind eine Klasse von Fehlern, bei denen die Anwendung den Arbeitsspeicher nicht mehr freigeben kann, wenn sie nicht mehr benötigt wird. Im Laufe der Zeit wirken sich Speicherlecks auf die Leistung sowohl der jeweiligen Anwendung als auch des Betriebssystems aus. Ein großes Leck kann aufgrund übermäßiger Pagings zu unannehmbaren Antwortzeiten führen. Schließlich wird die Anwendung sowie andere Teile des Betriebssystems Fehler auftreten.

Windows werden alle Speicher freizugeben, die der Anwendung zur Beendigung des Prozesses zugewiesen werden, sodass kurze Anwendungen keine Auswirkungen auf die Gesamtsystemleistung haben. Allerdings können Lecks in langfristig ausgeführten Prozessen wie Diensten oder sogar Explorer-Plug-Ins die Systemsicherheit stark beeinträchtigen und den Benutzer dazu zwingen, Windows neu zu starten, um das System wieder nutzbar zu machen.

Anwendungen können Arbeitsspeicher im Namen mehrerer Mittel zuweisen. Jede Art der Zuordnung kann zu einem Leck führen, wenn nach der Verwendung nicht freigestellt wird. Nachfolgend finden Sie einige Beispiele für allgemeine Zuordnungsmuster:

  • Heap-Speicher über die HeapAlloc-Funktion oder deren C/C++-Laufzeitäquivalente malloc oder neu
  • Direkte Zuordnungen aus dem Betriebssystem über die VirtualAlloc-Funktion .
  • Kernel-Handle, die über Kernel32-APIs wie CreateFile, CreateEvent oder CreateThread erstellt wurden, halten Sie kernelspeichern im Auftrag der Anwendung fest.
  • GDI- und USER-Handle, die über User32- und Gdi32-APIs erstellt wurden (standardmäßig verfügt jeder Prozess über ein Kontingent von 10.000 Handlen)

Bewährte Methoden

Die Überwachung des Ressourcenverbrauchs Ihrer Anwendung im Laufe der Zeit ist der erste Schritt bei der Erkennung und Diagnose von Speicherlecks. Verwenden Sie Windows Task-Manager, und fügen Sie die folgenden Spalten hinzu: "Commitgröße", "Handle", "Benutzerobjekte" und "GDI-Objekte". Dadurch können Sie einen Basisplan für Ihre Anwendung einrichten und die Ressourcennutzung im Laufe der Zeit überwachen.

Screenshot that shows the 'Processes' page in Windows Task Manager.

Die folgenden Microsoft-Tools bieten ausführlichere Informationen und können ihnen helfen, Lecks für die verschiedenen Zuordnungstypen in Ihrer Anwendung zu erkennen und zu diagnostizieren:

  • Leistungsmonitor und Ressourcenmonitor sind Teil Windows 7 und können die Ressourcennutzung über die Zeit überwachen und graphieren.
  • Die neueste Version von Application Verifier kann Heap-Lecks auf Windows 7 diagnostizieren.
  • UMDH, das Teil der Debugtools für Windows ist, analysiert die Heap-Speicherzuweisungen für einen bestimmten Prozess und kann dabei helfen, Lecks und andere ungewöhnliche Nutzungsmuster zu finden.
  • Xperf ist ein anspruchsvolles Leistungsanalysetool mit Unterstützung für heap-Zuordnungsablaufverfolgungen
  • CRT Debug Heap verfolgt Heap-Zuordnungen und kann Ihnen beim Erstellen ihrer eigenen Heap-Debugfeatures helfen.

Bestimmte Codierungs- und Entwurfspraktiken können die Anzahl der Lecks in Ihrem Code einschränken.

  • Verwenden Sie intelligente Zeiger im C++-Code sowohl für Heap-Zuordnungen als auch für Win32-Ressourcen wie Kernel HANDLEs. Die C++-Standardbibliothek stellt die auto_ptr Klasse für Heapzuweisungen bereit. Für andere Zuordnungstypen müssen Sie Ihre eigenen Klassen schreiben. Die ATL-Bibliothek bietet eine umfangreiche Gruppe von Klassen für die automatische Ressourcenverwaltung für heap-Objekte und Kernelhandpunkte
  • Verwenden Sie compilerinterne Features wie _com_ptr_t , um Ihre COM-Schnittstellenzeiger in "intelligente Zeiger" zu kapseln und zu unterstützen, um die Referenzzählung zu unterstützen. Es gibt ähnliche Klassen für andere COM-Datentypen: _bstr_t und _variant_t
  • Überwachen Sie ihre .NET-Code ungewöhnlichen Speichernutzung. Verwalteter Code ist nicht immun für Speicherlecks. Siehe "Nachverfolgen von verwalteten Speicherlecks" zur Suche nach GC-Lecks
  • Achten Sie auf Leckmuster im clientseitigen Webcode. Zirkelbezüge zwischen COM-Objekten und Skriptmodulen wie JScript können zu großen Lecks in Webanwendungen führen. "Grundlegendes und Lösen von Internet Explorer-Leak-Mustern" enthält weitere Informationen zu diesen Arten von Lecks. Sie können den JavaScript-Speicherlecksdetektor verwenden, um Speicherlecks in Ihrem Code zu debuggen. Während Windows Internet Explorer 8, das mit Windows 7 ausgeliefert wird, die meisten dieser Probleme verringert, sind ältere Browser immer noch anfällig für diese Fehler.
  • Vermeiden Sie die Verwendung mehrerer Exitpfade aus einer Funktion. Zuordnungen, die Variablen im Funktionsbereich zugewiesen sind, sollten am Ende der Funktion in einem bestimmten Block freigestellt werden.
  • Verwenden Sie keine Ausnahmen in Ihrem Code, ohne alle lokalen Variablen in Funktionen freizuweisen. Wenn Sie systemeigene Ausnahmen verwenden, können Sie alle Ihre Zuordnungen innerhalb des __finally blocks freigeben. Wenn Sie C++-Ausnahmen verwenden, müssen alle Ihre Heap- und Behandeln von Zuordnungen in intelligente Zeiger umgebrochen werden.
  • Verwerfen oder erneutisieren eines PROPVARIANT-Objekts ohne Aufrufen der PropVariantClear-Funktion

Allgemeine Zuordnungsmuster:

Microsoft Tools:

Weitere Links: