Was sind private Bytes, virtuelle Bytes, Arbeitssatz?

Ich versuche, das Dienstprogramm perfmon Windows zu verwenden, um Speicherlecks in einem process zu beheben.

So erklärt perfmon die Begriffe:

Working Set ist die aktuelle Größe des Arbeitssatzes dieses processes in Bytes. Der Arbeitssatz ist der Satz von Speicherseiten, die kürzlich von den Threads im process berührt wurden. Wenn der freie Speicher im Computer über einem Schwellenwert liegt, verbleiben Seiten im Arbeitssatz eines processes, auch wenn sie nicht verwendet werden. Wenn der freie Speicher einen Schwellenwert unterschreitet, werden die Seiten von den Arbeitssätzen abgeschnitten. Wenn sie benötigt werden, werden sie wieder in das Working Set zurückgeschrieben, bevor sie den Hauptspeicher verlassen.

Virtuelle Bytes ist die aktuelle Größe des virtuellen Adressraums, den der process verwendet, in Byte. Die Verwendung von virtuellem Adressraum bedeutet nicht notwendigerweise die entsprechende Verwendung von Festplatten- oder Hauptspeicherseiten. Der virtuelle Raum ist endlich und der process kann seine Fähigkeit einschränken, Bibliotheken zu laden.

Private Bytes ist die aktuelle Speichergröße in Bytes, die dieser process zugewiesen hat und die nicht mit anderen processen gemeinsam genutzt werden kann.

Das sind die Fragen, die ich habe:

Sind es die privaten Bytes, die ich messen sollte, um sicher zu sein, dass der process irgendwelche Lücken aufweist, da es keine gemeinsam genutzten Bibliotheken mit sich bringt und irgendwelche Lecks, wenn sie passieren, von dem process selbst stammen?

Wie viel Speicher wird insgesamt verbraucht? Sind es die virtuellen Bytes oder ist es die Summe von virtuellen Bytes und Working Set?

Gibt es eine Beziehung zwischen privaten Bytes, Working Set und virtuellen Bytes?

Gibt es andere Tools, die eine bessere Vorstellung von der Speichernutzung geben?

Die kurze Antwort auf diese Frage ist, dass keiner dieser Werte ein zuverlässiger Indikator dafür ist, wie viel Speicher eine ausführbare Datei tatsächlich verwendet, und keine davon ist wirklich geeignet, ein Speicherleck zu debuggen.

Private Bytes beziehen sich auf die Menge an Speicher, die die ausführbare Datei des processes angefordert hat – nicht notwendigerweise die Menge, die tatsächlich verwendet wird . Sie sind “privat”, weil sie (normalerweise) speicherkartenartige Dateien (dh freigegebene DLLs) ausschließen. Aber – hier ist der Haken – sie schließen nicht unbedingt den von diesen Dateien zugewiesenen Speicher aus. Es gibt keine Möglichkeit zu sagen, ob eine Änderung in privaten Bytes aufgrund der ausführbaren Datei selbst oder aufgrund einer verknüpften Bibliothek war. Private Bytes sind auch nicht ausschließlich physikalischer Speicher; Sie können auf die Festplatte oder in die Liste der Standby-Seiten ausgelagert werden (dh sie werden nicht mehr verwendet, aber auch noch nicht ausgelagert).

Working Set bezieht sich auf den gesamten physischen Speicher (RAM), der vom process verwendet wird. Im Gegensatz zu privaten Bytes umfasst dies jedoch auch Speicherabbilddateien und verschiedene andere Ressourcen, so dass es eine noch weniger genaue Messung als die privaten Bytes ist. Dies ist der gleiche Wert, der in der “Mem Usage” des Task-Managers gemeldet wird und in den letzten Jahren zu endlosen Verwirrungen geführt hat. Speicher im Arbeitssatz ist “physisch” in dem Sinne, dass er ohne einen Seitenerrors adressiert werden kann; Die Liste der Standby-Seiten befindet sich jedoch weiterhin physisch im Arbeitsspeicher, wird jedoch im Arbeitssatz nicht angezeigt. Daher kann es vorkommen, dass die “Mem Usage” plötzlich fällt, wenn Sie eine Anwendung minimieren.

Virtuelle Bytes sind der gesamte virtuelle Adressraum, der vom gesamten process belegt wird. Dies ist wie der Arbeitssatz in dem Sinne, dass Speicherabbilddateien (gemeinsame DLLs) enthalten sind, aber auch Daten in der Bereitschaftsliste und Daten, die bereits ausgelagert wurden und sich irgendwo in einer Auslagerungsdatei befinden. Die Gesamtzahl virtueller Bytes, die von jedem process auf einem System mit hoher Auslastung verwendet werden, führt zu erheblich mehr Arbeitsspeicher als die Maschine tatsächlich hat.

Die Beziehungen sind also:

  • Private Bytes sind das, was Ihre App tatsächlich zugewiesen hat, aber auch die Verwendung der Auslagerungsdatei;
  • Working Set sind die nicht ausgelagerten privaten Bytes plus Speicherabbilddateien;
  • Virtuelle Bytes sind das Working Set sowie die ausgelagerten privaten Bytes und die Standby-Liste.

Es gibt ein anderes Problem hier; Genauso wie gemeinsam genutzte Bibliotheken Speicher in Ihrem Anwendungsmodul reservieren können, was zu potenziellen Fehlalarmen führen kann, die in den privaten Bytes Ihrer App gemeldet werden, kann Ihre Anwendung auch Speicher in den gemeinsam genutzten Modulen zuordnen, was zu falsch negativen Ergebnissen führt . Das bedeutet, dass Ihre Anwendung tatsächlich einen Speicherverlust hat, der sich niemals in den privaten Bytes manifestiert. Unwahrscheinlich, aber möglich.

Private Bytes sind eine sinnvolle Annäherung an die Menge an Speicher, die Ihre ausführbare Datei verwendet, und können dazu verwendet werden, eine Liste potentieller Kandidaten für ein Speicherleck einzugrenzen; Wenn Sie die Zahl ständig und endlos wachsen und wachsen sehen, sollten Sie diesen process auf ein Leck überprüfen. Dies kann jedoch nicht beweisen, dass ein Leck vorliegt oder nicht.

Eines der effektivsten Tools zum Erkennen / Korrigieren von Speicherverlusten in Windows ist eigentlich Visual Studio (Link geht zur Seite bei der Verwendung von VS für Speicherlecks, nicht auf der Produktseite). Rational Purify ist eine andere Möglichkeit. Microsoft hat auch ein allgemeineres Best Practices-Dokument zu diesem Thema. In dieser vorherigen Frage sind weitere Tools aufgeführt.

Ich hoffe, das macht ein paar Dinge klar! Das Aufspüren von Speicherlecks ist eine der schwierigsten Aufgaben beim Debugging. Viel Glück.

Sie sollten nicht versuchen, Perfmon, Task-Manager oder ein ähnliches Tool zu verwenden, um Speicherlecks zu ermitteln. Sie sind gut zum Erkennen von Trends, aber nicht viel mehr. Die Zahlen, die sie absolut angeben, sind zu vage und aggregiert, um für eine bestimmte Aufgabe wie die Erkennung von Speicherlecks nützlich zu sein.

Eine vorherige Antwort auf diese Frage hat eine großartige Erklärung dafür gegeben, was die verschiedenen Typen sind.

Sie fragen nach einer Toolempfehlung: Ich empfehle Memory Validator. Kann Anwendungen überwachen, die Milliarden von Speicherzuweisungen machen.

http://www.softwareverify.com/cpp/memory/index.html

Haftungsausschluss: Ich habe Memory Validator entwickelt.

Die Definition der Perfmon-Counter wurde seit dem Anfang gebrochen und scheint aus irgendeinem Grund zu schwer zu korrigieren.

Eine gute Übersicht über die Windows-Speicherverwaltung finden Sie im Video ” Mysteries of Memory Management Revealed ” auf MSDN: Es behandelt mehr Themen als benötigt, um Speicherlecks zu verfolgen (zB Working-Set-Management), gibt aber genügend Details in den relevanten Themen.


Um Ihnen einen Hinweis auf das Problem mit den Beschreibungen der Perfmon-Counter zu geben, finden Sie hier die Insidergeschichte über private Bytes von ” Private Bytes Performance Counter – Achtung! ” Auf MSDN:

F: Wann ist ein privates Byte kein privates Byte?

A: Wenn es nicht resident ist.

Der Zähler “Private Bytes” meldet die Commit-Gebühr des processes. Das heißt, die Menge an Speicherplatz, die in der Auslagerungsdatei zugewiesen wurde, um den Inhalt des privaten Speichers im Falle eines Austausches zu speichern. Hinweis: Ich vermeide das Wort “reserviert” wegen möglicher Verwechslungen mit virtuellem Speicher im reservierten Zustand, der nicht festgeschrieben ist.


Von ” performancesplanung ” auf MSDN:

3.3 Private Bytes

3.3.1 Beschreibung

Privater Speicher ist definiert als Speicher, der für einen process reserviert ist, der nicht von anderen processen gemeinsam genutzt werden kann. Dieser Speicher ist teurer als der gemeinsame Speicher, wenn mehrere solcher processe auf einer Maschine ausgeführt werden. Privater Speicher in (traditionellen) nicht verwalteten Dlls besteht normalerweise aus C ++ – Statik und liegt in der Größenordnung von 5% des gesamten Arbeitssatzes der DLL.

Es gibt eine interessante Diskussion hier: http://social.msdn.microsoft.com/Forums/en-US/vcgeneral/thread/307d658a-f677-40f2-bdef-e6352b0bfe9e/ Mein Verständnis dieses Threads ist, dass kleine Zuweisungen frei sind nicht in privaten Bytes oder Working Set.

Um es kurz zu machen:

wenn ich rufe

p=malloc(1000); free(p); 

dann spiegeln die privaten Bytes nur die Zuordnung wider, nicht die Freigabe.

wenn ich rufe

 p=malloc(>512k); free(p); 

dann spiegeln die privaten Bytes die Zuordnung und die Freigabe richtig wider.