Mindestens 504 KB Speicherverbrauch

8

Wenn ich ein paar Experimente gemacht habe, während ich C gelernt habe, bin ich auf etwas Seltsames gestoßen. Das ist mein Programm:

%Vor%

Bei der Kompilierung beträgt die Dateigröße der ausführbaren Datei 8496 Bytes (im Vergleich zur 26-Byte-Quelle!). Dies ist verständlich, wenn sleep aufgerufen wird und die Anweisungen zum Aufruf in die ausführbare Datei geschrieben werden. Ein weiterer Punkt ist, dass die ausführbare Datei ohne den Ruhezustand 4312 Byte wird.

%Vor%

Meine Hauptfrage ist, was passiert, wenn das erste Programm ausgeführt wird. Ich benutze clang zum kompilieren und Mac OS X um es zu starten. Das Ergebnis (laut Activity Monitor) ist, dass das Programm 504 KB "Real Memory" verwendet. Warum ist es so groß, wenn das Programm nur 4KB ist? Ich gehe davon aus, dass die ausführbare Datei in den Speicher geladen wird, aber ich habe nichts außer einem Schlafanruf getan. Warum braucht mein Programm 500 KB, um fünf Sekunden lang schlafen zu können?

Übrigens ist der Grund, warum ich den Schlafmodus nutze, darin zu sehen, wie viel Speicher der Activity Monitor überhaupt benutzt.

Ich frage einfach aus Neugier, Prost!

    
lukey 14.10.2013, 09:05
quelle

2 Antworten

7

Wenn Sie ein C-Programm kompilieren, wird es in eine ausführbare Datei eingebunden. Obwohl Ihr Programm sehr klein ist, wird es mit der C-Laufzeit verbunden, die zusätzlichen Code enthält. Es kann zu einer Fehlerbehandlung kommen und diese Fehlerbehandlung schreibt möglicherweise auf die Konsole und dieser Code kann sprintf enthalten, was Ihrer Anwendung einen gewissen Fußabdruck hinzufügt. Sie können den Linker bitten, eine Karte des Codes in Ihrer ausführbaren Datei zu erstellen, um zu sehen, was tatsächlich enthalten ist.

Außerdem enthält eine ausführbare Datei mehr als Maschinencode. Es wird verschiedene Tabellen für Daten und dynamische Verknüpfungen geben, die die Größe der ausführbaren Datei erhöhen, und es kann auch etwas verschwendet werden, da die verschiedenen Teile in Blöcken gespeichert sind.

Die C-Laufzeit wird initialisiert, bevor main aufgerufen wird. Dies führt dazu, dass sowohl Code geladen wird (z. B. durch dynamisches Verknüpfen mit verschiedenen Betriebssystemfunktionen) als auch Speicher für einen Heap, einen Stack für jeden Thread, zugewiesen wird und wahrscheinlich auch einige statische Daten. Nicht alle diese Daten werden möglicherweise als "realer Speicher" angezeigt. Die Standard-Stapelgröße unter OS X scheint 8 MB zu betragen, und Ihre Anwendung verwendet immer noch viel weniger.

    
Martin Liversage 14.10.2013, 09:36
quelle
2

In diesem Fall nehme ich an, dass der beobachtete Größenunterschied maßgeblich durch dynamisches Verknüpfen verursacht wird.

Linker setzen üblicherweise keinen gemeinsamen Code in die ausführbaren Binärdateien, sondern sie reservieren die Informationen und der Code wird geladen, wenn die Binärdatei geladen wird. Hier wird dieser gemeinsame Code in den Dateien shared object(SO) oder dynamically linked library(DLL) gespeichert.

%Vor%

Auch hier lese ich, was in der Erinnerung eines Prozesses steckt:

  • Es müssen die notwendigen dynamischen Bibliotheken geladen werden:

    Hier gibt ldd das Ergebnis der dynamischen Bibliotheken an, die geladen werden sollen, wenn die Binärdatei aufgerufen wird. Diese Bibliotheken befinden sich in dem Teil, in dem sie durch Aufruf des mmap Systemaufrufs abgerufen wurden.

    %Vor%
  • Es gibt Abschnitte wie .data , .code , die für Daten aus Ihrer Binärdatei zugewiesen werden sollen.

    Dieser Teil existiert in der binären ausführbaren Datei, daher sollte die Größe nicht größer sein als die Datei selbst. Inhalt wurde beim Laden einer ausführbaren Binärdatei kopiert.

  • Es gibt Abschnitte wie .bss und auch die Stack-Zone, die während der Ausführung des Programms dynamisch verwendet werden soll.

    Dieser Teil existiert nicht in der binären ausführbaren Datei, daher kann die Größe sehr groß sein, ohne von der Größe der Datei selbst beeinflusst zu werden.

starrify 14.10.2013 10:19
quelle

Tags und Links