Warum ist VSIZE für 64-Bit-Linux-Prozesse so viel größer?

8

Meine grundlegende Frage ist, warum ist das VSIZE für einen 64-Bit-Prozess so viel größer als das des exakt gleichen Programms für 32 Bit kompiliert?

Das Folgende ist die Ausgabe der Datei / proc / & lt; pid & gt; / maps für den 32-Bit-Prozess.

%Vor%

Was zu einem Gesamt-VSIZE von 3656 führt.

Das Folgende ist die Ausgabe der Datei / proc / & lt; pid & gt; / maps für den 64-Bit-Prozess.

%Vor%

Was zu einem VSIZE von 18480 führt.

Der Hauptunterschied zwischen den 2 Karten sind die folgenden Einträge aus den 64-Bit-Daten:

%Vor%

Welches Konto für 14316 des 18480 VSIZE.

Andere Experimente mit anderen Programmen scheinen zu zeigen, dass Sie in 64 Bit einen dieser privaten, nicht lesbaren, nicht schreibbaren, nicht ausführbaren Speicherbereiche für jede gemeinsam genutzte Bibliothek, die von dem Prozess verwendet wird, erhalten in 32 Bit gibt es kaum einen dieser Brocken.

Weiß jemand, was diese Speicherstücke sind?

Hinweis: Basierend auf einigen Antworten auf eine ähnliche Frage Was diese Speicherbereiche für, von einem Linux-Prozess? , das ist kein Multi-Thread-Prozess und es ist bereits kompiliert -fPIC.

    
user1983871 17.01.2013, 02:55
quelle

3 Antworten

8

Die hauptsächliche VSIZE-Differenz ergibt sich daraus, wie die PROT_NONE-Zuordnungen (Modus "--- p") der gemeinsam genutzten Bibliotheken im Fall der 32-Bit- und 64-Bit-Versionen durchgeführt werden.

Das sind genau die Mappings, die Sie entdeckt haben, um den Unterschied zu erzeugen.

Im Allgemeinen haben wir für jede geladene gemeinsame Bibliothek vier Abbildungen:

%Vor%

Das erste ist das Codesegment mit ausführbaren Berechtigungen, das zweite das PROT_NONE (mode ---) Mapping (auf die Seiten kann nicht zugegriffen werden) und die letzten beiden das Datensegment (read-only part und read write).

PROT_NONE hat die Größe MAXPAGESIZE und wird daher in den 32-Bit- und 64-Bit-Versionen unterschiedlich erstellt. Im Fall der 32-Bit-Version hat es eine Größe von 4 KB (MAXPAGESIZE für i386) und im Falle der 64-Bit-Version 2 MB (Standard MAXPAGESIZE für x86_64-Systeme).

Es sollte beachtet werden, dass dieser Speicher nicht tatsächlich verbraucht wird (er verbraucht nur Adressen des Adressraums), wie hier angemerkt:

Ссылка

"Dieses Extra kostet keinen RAM- oder Auslagerungsbereich, sondern adressiert nur den Platz in jedem Prozess, der auf 64-Bit-Plattformen reichlich vorhanden ist. Der Grund dafür liegt darin, dass Bibliotheken effizient gemeinsam genutzt werden können, aber die Implementierung ist ein bisschen seltsam. "

Nur ein letzter Trick, ich finde es einfacher, Speicherzuordnungen mit dem Dienstprogramm pmap zu überprüfen, als analysiert die Zuordnungsdatei und erzeugt eine einfacher zu lesende Ausgabe:

Für grundlegende Informationen:

%Vor%

Für erweiterte Informationen:

%Vor%     
alcachi 10.10.2013 16:33
quelle
1

[nicht wirklich eine Antwort ... über mein Wissen hinaus sprechen]

Wenn die Speichersegmente wirklich "privat, nicht lesbar, nicht beschreibbar, nicht ausführbar" sind, sollten sie niemals erwähnt werden, und obwohl sie im VIRTUELLEN Speicherbereich existieren, werden sie niemals einen realen Speicher belegen und deshalb nicht viel zu sorgen. (?)

Es muss eine Art Buchhaltungs- oder Fragmentierungsproblem sein. Da diese Teile Teil der Shared Libraries (* .so) sind, wurden diese Bibliotheken erstellt. Es hat wirklich nichts mit Ihrem Programm zu tun, außer es ist mit diesen Bibliotheken verbunden. Wenn Sie diese Bibliotheken nicht neu erstellen oder nicht verwenden möchten, gibt es nicht viel zu tun (und sowieso nicht viel zu gewinnen, da sie sowieso keinen echten Speicher verwenden sollten).

Vielleicht verwandt? In Was diese Speicherregionen für, von einem Linux Prozess?

@caf sagt einige Speichersegmente, die "--- p" sind "Guard-Seiten".

Das deutet darauf hin, dass sie existieren, nur um einen streunenden Zeiger oder Stack zu fangen, der zu einem fernen Fehler aufsteigt ... eine Art hartes Trennzeichen im Speicher, so dass das System einen allgemeinen Fehler erkennen und die Verarbeitung stoppen kann ein fataler Fehler, um überhaupt auf sie zu verweisen, und sie werden NIEMALS echten Speicher benutzen).

    
9mjb 24.03.2013 13:50
quelle
1

Um auf die Frage zu antworten, warum und was eine 64bit shared library ausmacht, gibt es ein Beispiel für das Laden von libc.so und das Auslesen, wie loader dynamische Bibliotheken lädt. Unten sind strace outputs für 32bit und 64bit ausführbare Dateien, die uns sagen, dass es Aufrufe an mmap & amp; %Code%.

%Vor%
%Vor%

Die beiden Dinge des Straces genau zu beobachten, muss untersucht werden,

1. Jeder von ihnen ordnet Speicher dreimal und 1 Aufruf mprotect genau nach dem ersten mprotect zu.

2. Vergleichen von mmap fordert 64bit & amp; 32bit hat mprotect & amp; 2093056B der Region geschützt bzw..

In dl-load.c , Subroutine _dl_map_object_from_fd () ordnet dynamische Bibliotheksspeichersegmente dem virtuellen Speicherbereich zu, indem erforderliche Berechtigungen und Nullfüllungen 4096B -Abschnitt der Bibliothek festgelegt und die Linkmapstruktur aktualisiert werden. Lassen Sie uns einen Teil des Codes für weitere Analysen erhalten,

%Vor%

Im obigen Code enthält .bss in l_phnum -Anweisung die Anzahl der Einträge im ELF-Programmheader. Idealerweise werden für jede Iteration alle Eintragssegmente abgebildet. Wenn for segment case zum ersten Mal auftritt, ist es im Grunde eine PT_LOAD oder .text Sektion, die mmapped wird (1. .rodata in strace) und zweite mmap Segment repräsentiert PT_LOAD Sektion wird gemappt (2. .data in strace). Bevor das zweite mmap -Segment zugeordnet wird, bleiben PT_LOAD und mapstart erhalten, die sich auf den Anfang und das Ende des Textabschnitts beziehen. In der nächsten mapend -Iteration, wenn das vorherige Segment PT_LOAD nicht mit dem aktuellen (.data) Segment mapend übereinstimmt, dann ist es ein Loch zwischen zwei mapstart Segmenten (bedeutet Lücke zwischen den Abschnitten PT_LOAD und .text ). Wenn es sich also um ein Loch zwischen Speicherbereichen mit Null-Berechtigungen handelt, schützt loader ( .data call in strace) es oder macht es unzugänglich. Geschützte Region für 64-Bit und 32-Bit-Prozess sind 511 Vs nur 1 Seite jeweils zu großen Speicher Chunk für 64-Bit-Bibliotheken hinzufügen.

Beweis für 64bit unzugängliche Region : Objdump für mprotect unten gibt uns einige virtuelle Adressen (VA) Statistiken, die wie folgt angemessen abgerundet werden,

%Vor%

Hier ist libc.so (0x00000000001b5000) nicht gleich PT_LOAD(1) mapend (0x00000000003b4000) was zu einem Speicherloch von 0x00000000001FF000 führt (In Dezimal PT_LOAD(2) mapstart ).

%Vor%

Am Anfang nimmt 64-Bit-Text eine höhere Darstellung von Befehlsbytes im Vergleich zu 32-Bit. Ähnlich ist die Größe von Zeigern auf 64 Bit 2093056B und 8B mehr Bytes. Außerdem ist die Ausrichtung der Datenstruktur eine 4 , die in 64 Bit ausgerichtet ist, wodurch die abgebildeten Bereiche größer werden.

Der einfache 8B -Befehl für Binärdateien kann den Unterschied zwischen den Speicherbereichen von 32/64 Bit-Programmen wie folgt anzeigen:

%Vor%     
Sunil Bojanapally 10.10.2013 13:21
quelle

Tags und Links