28 Stimmen

Stack- und Heap-Zuweisung

Ich beschäftige mich ein wenig mehr mit dem Speichermodell und habe Schwierigkeiten zu verstehen, wie viele Heaps in einem Prozess existieren.

Also, wenn wir 1 Prozess mit 5 Threads in es haben, bin ich richtig in sagen, dass wir 5 Stapel und 1 Heap haben würde?

Wenn ja, können die Threads gegenseitig auf die Stacks zugreifen (oder ist dies genau, warum sie separate Stacks haben, um Korruption zu verhindern), und wenn es nur 1 Heap, dann offensichtlich sie alle auf diesen Heap zugreifen, daher die Notwendigkeit für Sperren mit mehreren Threads? Habe ich das richtig verstanden?

41voto

Hans Passant Punkte 894572

Ja, jeder Thread hat seinen eigenen Stack. Das ist eine unabdingbare Notwendigkeit, denn auf dem Stack wird gespeichert, wohin eine Methode nach ihrer Beendigung zurückkehrt, er speichert die Rücksprungadresse. Da jeder Thread seinen eigenen Code ausführt, braucht er seinen eigenen Stack. Lokale Variablen und Methodenargumente werden ebenfalls dort gespeichert, was sie (normalerweise) thread-sicher macht.

Die Anzahl der Haufen ist ein komplizierteres Detail. Sie zählen 1 für den Garbage Collected Heap. Das ist aus Sicht der Implementierung nicht ganz korrekt, denn die drei Generationsheaps und der Large Object Heap sind logisch getrennte Heaps, so dass sich die Zahl auf vier erhöht. Dieses Implementierungsdetail wird wichtig, wenn Sie zu viel zuweisen.

Ein weiterer Punkt, den man in verwaltetem Code nicht ganz ignorieren kann, ist der Heap, in dem statische Variablen gespeichert werden. Er ist mit der AppDomain verbunden, statische Variablen leben so lange, wie die AppDomain lebt. In der .NET-Literatur wird er häufig als "Loader Heap" bezeichnet. Er besteht eigentlich aus 3 Heaps (Hochfrequenz-, Niederfrequenz- und Stub-Heap), auch Jitted Code und Typdaten werden dort gespeichert, aber das ist nur ein kleiner Teil der Details.

Weiter unten auf der Ignorierliste stehen die von nativem Code verwendeten Heaps. Zwei davon sind in der Marshal-Klasse leicht zu erkennen. Es gibt einen Standard-Prozess-Heap, aus dem Windows alloziert, ebenso Marshal.AllocHGlobal(). Und es gibt einen separaten Heap, in dem COM Daten speichert; Marshal.AllocCoTaskMem() belegt ihn. Schließlich hat jeder native Code, mit dem Sie interagieren, seinen eigenen Heap für seine Laufzeitunterstützung. Die Anzahl der Heaps, die von dieser Art von Code verwendet werden, ist nur durch die Anzahl der nativen DLLs begrenzt, die in Ihren Prozess geladen werden. Alle diese Heaps sind vorhanden, Sie haben nur selten direkt mit ihnen zu tun.

Also, mindestens 10 Haufen.

12voto

Jakub Konecki Punkte 44858

Kurz gesagt, ja .

Alle Threads eines Prozesses teilen sich denselben Heap, so dass sie Daten austauschen können. Jeder Thread hat seinen eigenen Stack, der sich auf die aktuelle Codeausführung in diesem Thread bezieht.

Eine sehr gute Quelle zum Thema Gewindeschneiden finden Sie hier: http://www.albahari.com/threading/

Ein Thread ist vergleichbar mit dem Betriebssystem Anwendung läuft. Genauso wie Prozesse auf einem Computer parallel laufen, laufen Threads innerhalb eines einzelnen Prozesses parallel. [ ] voneinander isoliert; Threads haben nur ein begrenztes Maß an Isolierung. Insbesondere teilen sich Threads den (Heap-)Speicher mit anderen Threads, die in derselben Anwendung laufen. Dies ist zum Teil der Grund, warum Threading nützlich: Ein Thread kann im Hintergrund Daten abrufen, zum Beispiel abrufen, während ein anderer Thread die Daten anzeigen kann, sobald sie eintreffen.

4voto

Hristo Iliev Punkte 70306

Threads sind getrennte Befehlsströme, die gleichzeitig im selben virtuellen Adressraum eines einzigen Prozesses laufen. Der Heap ist ein großer Speicherbereich, den das System jedem Prozess für seine eigene private Nutzung zur Verfügung stellt. Prozesse können ihre Heap-Größe anpassen und den Heap-Speicher nach eigenem Gutdünken nutzen. Threads können bei der Nutzung dieses Heap-Speicherplatzes zusammenarbeiten und auch zusätzliche private Speicherbereiche zuweisen, die als Thread lokale Speicher (TLS).

Da sich alle Threads denselben virtuellen Adressraum teilen, können sie direkt auf den Stapelspeicher des jeweils anderen zugreifen. Das bedeutet, dass ein Thread eine Variable auf seinem Stack als Argument an eine Funktion übergeben kann, die in einem anderen Thread läuft. Die Stapel der Threads sind jedoch insofern getrennt, als ein Thread niemals Werte in den Stapel eines anderen Threads schiebt oder verschiebt, sondern nur in seinen eigenen Stapelbereich. Da Stapel auf x86 und x86-64 nach unten wachsen, gibt es eine spezielle Seite am unteren Ende des Stapelspeichers eines jeden Threads - die so genannte Wächterseite . Der Stapelfehler tritt auf, wenn während des Betriebs des Stapels die Schutzseite erreicht wird.

In nicht verwalteten Sprachen wie C und C++ kann auf jeden Teil des Prozessspeichers durch die Verwendung von Zeigern nach Belieben zugegriffen werden. Ein Thread kann den Inhalt des Stapels eines anderen Threads völlig durcheinander bringen und so den zweiten Thread (und den Prozess als Ganzes) zum Absturz bringen. In C# können solche Dinge nicht außerhalb von unsafe Blöcke, da Stapel von der CLR verwaltet werden.

2voto

Lukasz Madon Punkte 14194

Dies ist Implementierung definiert, aber lassen Sie uns über die meisten gängigen modernen Betriebssysteme sprechen, da Sie C#-Tag hinzufügen.

wie viele Heaps in einem Prozess vorhanden sind.

Normalerweise 1 pro Prozess.

Also, wenn wir 1 Prozess mit 5 Threads in es haben, bin ich richtig in sagen, dass wir 5 Stapel und 1 Heap haben würde?

Ja. Jeder Thread verbraucht sofort 1 MB virtuellen Adressraum für den Thread-Stack.

Wenn ja, können die Threads gegenseitig auf die Stapel zugreifen (oder ist dies genau, warum Sie separate Stapel haben, um Korruption zu verhindern), und wenn es nur 1 Heap, dann offensichtlich Sie alle auf diesen Heap zugreifen, daher die Notwendigkeit für die Sperrung mit mehreren Threads? Habe ich das richtig verstanden?

Ja, moderne Umgebungen sind sehr gut sandboxed, daher können Sie nicht auf andere Thread-Stack von einem anderen Thread direkt.

CodeJaeger.com

CodeJaeger ist eine Gemeinschaft für Programmierer, die täglich Hilfe erhalten..
Wir haben viele Inhalte, und Sie können auch Ihre eigenen Fragen stellen oder die Fragen anderer Leute lösen.

Powered by:

X