Verhindern von Speicherverlusten in Windows Anwendungen
Betroffene Plattformen
Clients – Windows 7
Server – Windows Server 2008 R2
BESCHREIBUNG
Speicherverlusten sind eine Klasse von Fehlern, bei denen die Anwendung keinen Arbeitsspeicher mehr frei gibt, wenn sie nicht mehr benötigt wird. Im Laufe der Zeit wirken sich Speicherverlusten sowohl auf die Leistung der jeweiligen Anwendung als auch des Betriebssystems aus. Ein großer Leck kann aufgrund übermäßiger Paging zu inakzeptablen Antwortzeiten führen. Schließlich kommt es bei der Anwendung und anderen Teilen des Betriebssystems zu Ausfällen.
Windows bei Beendigung des Prozesses den gesamten von der Anwendung zugewiesenen Arbeitsspeicher frei, sodass anwendungen mit kurzer Ausführung keine erheblichen Auswirkungen auf die Gesamtleistung des Systems haben. Allerdings können Lecks in Prozessen mit langer Laufzeit wie Diensten oder sogar Explorer-Plug-Ins die Systemzuverlässigkeit stark beeinflussen und den Benutzer zwingen, Windows neu zu starten, um das System wieder nutzbar zu machen.
Anwendungen können Speicher in ihrem Namen auf mehrere Weisen zuordnen. Jede Art von Zuordnung kann zu einem Leck führen, wenn sie nach der Verwendung nicht wieder frei wird. Im Folgenden finden Sie einige Beispiele für allgemeine Zuordnungsmuster:
- Heapspeicher über die HeapAlloc-Funktion oder die entsprechenden C/C++-Laufzeitentsprechungen malloc oder new
- Direkte Zuordnungen vom Betriebssystem über die VirtualAlloc-Funktion.
- Kernelhandles, die über Kernel32-APIs wie CreateFile, CreateEventoder CreateThreaderstellt wurden, halten Kernelspeicher im Namen der Anwendung.
- Über User32- und Gdi32-APIs erstellte GDI- und USER-Handles (standardmäßig verfügt jeder Prozess über ein Kontingent von 10.000 Handles).
Bewährte Methoden
Die Überwachung des Ressourcenverbrauchs Ihrer Anwendung im Laufe der Zeit ist der erste Schritt bei der Erkennung und Diagnose von Speicherverlusten. Verwenden Windows Task-Manager, und fügen Sie die folgenden Spalten hinzu: "Commit Size", "Handles", "User Objects" und "GDI Objects". Auf diese Weise können Sie eine Baseline für Ihre Anwendung erstellen und die Ressourcennutzung im Laufe der Zeit überwachen.

Die folgenden Microsoft-Tools bieten ausführlichere Informationen und können helfen, Lecks für die verschiedenen Zuordnungstypen in Ihrer Anwendung zu erkennen und zu diagnostizieren:
- Leistungsmonitor und Ressourcenmonitor sind Teil von Windows 7 und können die Nutzung von Graphressourcen im Laufe der Zeit überwachen.
- Die neueste Version von Application Verifier heap leaks on Windows 7
- UMDH, das Teil der Debugtools für Windows ist, analysiert die Heapspeicherzuordnungen für einen bestimmten Prozess und kann helfen, Lecks und andere ungewöhnliche Verwendungsmuster zu finden.
- Xperf ist ein anspruchsvolles Leistungsanalysetool mit Unterstützung für Heapzuordnungs-Ablaufverfolgungen.
- CRT Debug Heap verfolgt Heapzuordnungen nach und kann ihnen helfen, eigene Heapdebugfeatures zu erstellen.
Bestimmte Codierungs- und Entwurfsmethoden können die Anzahl von Lecks in Ihrem Code begrenzen.
- Verwenden Sie intelligente Zeiger in C++-Code sowohl für Heapzuordnungen als auch für Win32-Ressourcen wie kernel HANDLE s. Die C++-Standardbibliothek stellt die auto _ ptr-Klasse für Heapzuordnungen zur Verfügung. Für andere Zuordnungstypen müssen Sie Eigene Klassen schreiben. Die ATL-Bibliothek bietet einen großen Satz von Klassen für die automatische Ressourcenverwaltung für Heapobjekte und Kernelhandles.
- Verwenden Sie systeminterne Compilerfeatures wie _ com _ ptr _ t, um Ihre COM-Schnittstellenzeker in "intelligente Zeiger" zu kapseln und die Verweiszählung zu unterstützen. Es gibt ähnliche Klassen für andere COM-Datentypen: _ bstr _ t und _ variant _ t
- Überwachen Sie die ungewöhnliche Speicherauslastung Ihres .NET-Codes. Verwalteter Code ist nicht ungnicht gegen Speicherverlusten. Informationen zum Aufspüren von GC-Lecks finden Sie unter "Nachverfolgen verwalteter Speicherverlusten".
- Beachten Sie Leak-Muster im clientseitigen Webcode. Zirkelverweise zwischen COM-Objekten und Skript-Engines wie JScript können große Lecks in Webanwendungen verursachen. "Understanding and Solving Internet Explorer Leak Patterns" enthält weitere Informationen zu diesen Arten von Lecks. Sie können die JavaScript-Speicherverlusterkennung verwenden, um Speicherverlusten in Ihrem Code zu debuggen. Während Windows Internet Explorer 8, der mit Windows 7 veröffentlicht wird, die meisten dieser Probleme entschärft, sind ältere Browser weiterhin anfällig für diese Fehler.
- Vermeiden Sie die Verwendung mehrerer Exitpfade aus einer Funktion. Zuordnungen, die Variablen im Funktionsumfang zugewiesen sind, sollten in einem bestimmten Block am Ende der Funktion frei werden.
- Verwenden Sie keine Ausnahmen in Ihrem Code, ohne alle lokalen Variablen in Funktionen frei zu machen. Wenn Sie native Ausnahmen verwenden, geben Sie alle Ihre Zuordnungen innerhalb des _ _ finally-Blocks frei. Wenn Sie C++-Ausnahmen verwenden, müssen alle Ihre Heap- und Handlezuordnungen in intelligente Zeiger umschlossen werden.
- Verwerfen oder erneut initialisieren Sie ein PROPVARIANT-Objekt nicht, ohne die PropVariantClear-Funktion aufrufen zu müssen.
Links zu Ressourcen
Allgemeine Zuordnungsmuster:
- Heapzuordnungsfunktion
- Speicherzuordnungsfunktion
- New-Operator (C++)
- Virtuelle Zuordnungsfunktion
- Kernelobjekte
- GDI-Objekthandles
- Benutzeroberfläche Objekthandles
Microsoft-Tools:
- Application Verifier
- Debuggingtools für Windows
- Speicherabbild-Heap im Benutzermodus
- Trace Capture, Processing, and Analysis Tool
- CRT-Debug heap
Weitere Links:
- auto _ ptr-Klasse
- Active Template Library (ATL)-Speicherklassen
- _com _ ptr _ t Object
- _bstr _ t-Klasse
- _variant _ yt-Klasse
- "Nachverfolgen verwalteter Speicherverlusten"
- "Understanding and Solving Internet Explorer Leak Patterns" (Verstehen und Lösen von Internet Explorer Verlustmustern)
- "JavaScript Memory Leak Detector"
- Entschärfung von Zirkelspeicherverlust (in Browsern):
- try-finally-Anweisung
- PROPVARIANT-Struktur
- PropVariantClear-Funktion