2009-11-08 6 views
8

Wie erkennen Sie programmgesteuert die Anzahl der Bytes, die vom Prozess auf Heap zugewiesen wurden? Dieser Test sollte vom Prozess selbst funktionieren.Wie erkennen Sie programmatisch die Anzahl der Bytes, die vom Prozess auf Heap zugewiesen wurden?

+1

Warum? Wenn wir wissen, warum, dann ist es vielleicht einfacher, etwas zu empfehlen, als die Millionen und 1 (gefährlichen) Techniken, die es gibt, zu verwerfen. –

+0

Ich habe Speicherverlust, der von Valgrind nicht gefunden werden kann. – Pirks

Antwort

2

Eine spekulative Lösung zu berechnen: new und delete Operatoren neu definieren.

Bei jedem Operatorruf new wird eine Anzahl zuzuteilender Bytes übergeben. Weisen Sie ein bisschen mehr Speicher zu und speichern Sie die Menge der Bytes, die Sie zugewiesen haben. Fügen Sie diesen Betrag der globalen Variablen hinzu, die die Heap-Größe enthält.

Unter delete Bedieneraufruf, überprüfen Sie den Wert, den Sie gespeichert haben, bevor Sie den Speicher entsorgen. Subtrahiere es von dieser globalen Variable.

0

Andere dann alle Ihre Speicherzuordnungen zu verfolgen Ich glaube nicht, gibt es eine Möglichkeit, die Heap-Größe oder Nutzung

3

Es gibt keine einfache, automatische Weg, es zu tun, wenn das ist, was Sie fragen. Sie müssen die Heap-Allokationen manuell manuell mit einer Counter-Variablen verfolgen. Das Problem ist, dass es schwierig ist, zu steuern, welche Teile Ihres Programms Speicher auf dem Heap zuweisen, besonders wenn Sie viele Bibliotheken außerhalb Ihrer Kontrolle verwenden. Um die Dinge noch weiter zu verkomplizieren, gibt es zwei Möglichkeiten, wie ein Programm Heapspeicher zuweisen kann: new oder malloc. (Ganz zu schweigen von direkten OS-Anrufen wie sbrk.)

Sie können override global operator new, und jeder Anruf zu neuen erhöhen eine globale Tally. Dies schließt jedoch nicht notwendigerweise Zeiten ein, wenn Ihr Programm malloc aufruft oder wenn Ihr Programm eine klassenspezifische new-Überschreibung verwendet. Sie können auch malloc mit einem Makro überschreiben, aber das ist nicht unbedingt übertragbar. Und Sie müssten auch alle Variationen von malloc, wie realloc, calloc usw. überschreiben. All dies wird weiter durch die Tatsache kompliziert, dass bei einigen Implementierungen new selbst malloc anrufen kann.

Also, im Wesentlichen ist es sehr schwierig, dies in Ihrem Programm richtig zu tun. Ich würde stattdessen die Verwendung eines Speicher-Profiler-Tools empfehlen.

6

Es gibt eine Reihe von Möglichkeiten.

Wie genau soll es sein? Sie können einige nützliche Daten über cat/proc/$ {PID}/status | grep VmData.

Sie können #define Ihre eigene malloc(), realloc(), calloc() und free() Funktionen, die wirklichen Funktionen hinter Ihren eigenen Zähler wickeln. Mit __FILE__, __LINE__, & __func__ können Sie hier wirklich coole Dinge tun, um Kernlecks in einfachen Tests zu erkennen. Aber es wird nur Ihren eigenen Code instrumentieren!

(In ähnlicher Weise können Sie auch die Standard neu definieren Betreiber neue und Operator Methoden, beide Array und Nicht-Array-Varianten, und beide werfen std :: bad_alloc und std :: nothrow_t Varianten löschen. Auch hier wird Ihr eigener Code nur Instrument)

(Bitte beachten Sie: bei den meisten C++ Systemen ruft neue schließlich malloc (!).. Es nicht muss Insbesondere bei in-pl Ass neu! Aber in der Regel neue macht Gebrauch von malloc(). (Oder es arbeitet auf einem Bereich des Speichers, der malloc vorher war() "ed.) Erhalten Sie würden sonst in wirklich funky stuff mit mehreren Heap-Manager ...)

Sie sbrk verwenden (0) um zu sehen, wo das Datensegment gerade eingestellt ist. Das ist nicht so toll. Es ist eine sehr grobe Messung, und es berücksichtigt keine Lücken (ungenutzte Speicherbereiche) im Heap. (Du bist viel besser dran mit dem Vmdata Linie von /proc/$ {PID}/Status.) Aber wenn Sie schauen, nur für eine allgemeine Idee ...

Sie abfangen können malloc()/free()/etc indem Sie Ihre eigene gemeinsam genutzte Bibliothek schreiben und Ihren Prozess erzwingen, ihn anstelle der realen Versionen über LD_PRELOAD zu verwenden. Sie können verwenden dlopen()/dlsym() laden & rufen Sie die * real * malloc()/free()/etc. Das funktioniert ganz schön. Der ursprüngliche Code ist unverändert, nicht einmal neu kompiliert. Seien Sie sich bei der Kodierung dieser Bibliothek jedoch auf eintretende Situationen bewusst, und dass Ihr Prozess anfänglich malloc()/calloc()/realloc() vor dlopen()/dlsym() aufruft, kann das Laden der echten Funktionen abgeschlossen werden.

Sie könnten Tools wie Valgrind überprüfen, obwohl das wirklich mehr auf Speicherlecks ausgerichtet ist.


Dann wieder, vielleicht mtrace() ist das, was Sie wollen? Oder __malloc_hook? Sehr proprietärer (GNU) & Nicht-Standard ... Aber Sie „Linux“ getaggt ...

1

Da Sie Ihre Frage ‚Linux‘ mit Tags versehen haben, es könnte auf einige der Informationen im /proc Verzeichnis zur Verfügung gestellt suchen helfen. Ich habe das nicht viel erforscht, also kann ich dir nur einen Ausgangspunkt geben.

/proc/<your programs pid> enthält Dateien mit einigen Informationen über Ihren Prozess aus der Sicht des Kernels. Es gibt einen Symlink /proc/self, der immer über den Prozess Ihrer Untersuchung davon abgeht.

Die am meisten interessierenden Dateien sind stat, statm und status. Letzteres ist besser lesbar, während die ersten beiden die gleichen Informationen in einem maschinenlesbaren Format enthalten.

Ein Ausgangspunkt für die Interpretation des Inhalts dieser Dateien finden Sie in der Manpage proc(5).

6

Ich denke mallinfo() ist das, was Sie wollen:

#include <malloc.h> 


struct mallinfo *info; 

info = mallinfo(); 

printf ("total allocated space: %llu bytes\n", info->uordblks); 
printf ("total free space:  %llu bytes\n", info->fordblks); 

Die Struktur mallinfo Struktur ist technisch und spezifisch für die malloc() -Implementierung. Aber die Information, die du willst, ist da drin. Hier ist, wie ich die Werte berichten:

mallinfo.arena = "Total Size (bytes)" 
mallinfo.uordblks = "Busy size (bytes)" 
mallinfo.fordblks = "Free size (bytes)" 
mallinfo.ordblks = "Free blocks (count)" 
mallinfo.keepcost = "Top block size (bytes)" 
mallinfo.hblks = "Blocks mapped via mmap() (count)" 
mallinfo.hblkhd = "Bytes mapped via mmap() (bytes)" 

Diese beiden sind angeblich nicht verwendet, aber sie scheinen auf meinem System zu ändern, und damit könnte gelten:

mallinfo.smblks = "Fast bin blocks (count)" 
mallinfo.fsmblks = "Fast bin bytes (bytes)" 

Und der andere interessante Wert ist zurückgegeben von "sbrk (0)"

+0

Sieht veraltet oder nicht nützlich im Jahr 2017 für 64-Bit-Maschinen, für Speicher größer als 2 GB zugewiesen :( – Makesh

Verwandte Themen