Was und wo sind die stack und heap?
Programmiersprache Bücher, die erklären, dass Wert-Typen, die erstellt werden, auf die stack - und Referenz-Typen erstellt, auf der heap, ohne zu erklären, was diese beiden Dinge sind. Ich habe nicht gelesen, eine klare Erklärung dafür. Ich verstehe, was einen Stapel ist. Aber,
- Wo und was Sie sind (körperlich, eine echte computer-Speicher)?
- Inwieweit sind Sie gesteuert durch das Betriebssystem oder die Sprache, Laufzeit?
- Was ist Ihr Anwendungsbereich?
- Was bestimmt die Größe eines jeden von Ihnen?
- Was macht man schneller?
eine wirklich gute Erklärung finden Sie hier Was ist der Unterschied zwischen einem stack und einen heap?
Auch (wirklich) gut: codeproject.com/Articles/76153/... (stack/heap Teil)
youtube.com/watch?v=clOUdVDDzIM&spfreload=5
Verwandte, finden Sie unter Stapel Clash. Die Stack-Clash-remediations betroffene einige Aspekte der system-Variablen und Verhaltensweisen wie
Die Definitionen für stack und heap nicht hängt davon ab, Wert-und Referenztypen löschen. In anderen Worten, der stack und der heap werden können vollständig definiert, auch wenn Wert-und Referenz-Typen, die nie existierte. Weiter, wenn das Verständnis, Wert-und Referenz-Typen, der stack ist einfach ein Implementierungsdetail. Pro Eric Lippert: Der Stack Ist Eine Implementierung Detail, Part One.
Auch (wirklich) gut: codeproject.com/Articles/76153/... (stack/heap Teil)
youtube.com/watch?v=clOUdVDDzIM&spfreload=5
Verwandte, finden Sie unter Stapel Clash. Die Stack-Clash-remediations betroffene einige Aspekte der system-Variablen und Verhaltensweisen wie
rlimit_stack
. Siehe auch Red Hat Problem 1463241Die Definitionen für stack und heap nicht hängt davon ab, Wert-und Referenztypen löschen. In anderen Worten, der stack und der heap werden können vollständig definiert, auch wenn Wert-und Referenz-Typen, die nie existierte. Weiter, wenn das Verständnis, Wert-und Referenz-Typen, der stack ist einfach ein Implementierungsdetail. Pro Eric Lippert: Der Stack Ist Eine Implementierung Detail, Part One.
InformationsquelleAutor mattshane | 2008-09-17
Du musst angemeldet sein, um einen Kommentar abzugeben.
Den Stapel, ist die Erinnerung beiseite als scratch-Speicherplatz für einen thread der Ausführung. Wenn eine Funktion aufgerufen wird, wird ein block ist reserviert auf dem stack für lokale Variablen und einige buchhalterische Daten. Wenn die Funktion zurückgibt, wird der block wird nicht verwendete und verwendet werden können, das nächste mal, wenn eine Funktion aufgerufen wird. Der stack ist immer reserviert in einem LIFO - (last in first out) - Reihenfolge; die erst kürzlich reservierten block wird immer der nächste block freigegeben werden. Dies macht es wirklich einfach, den überblick zu behalten-Stapel; die Befreiung einen block aus dem Stapel ist nichts mehr als eine Anpassung Zeiger.
Wird der heap-Speicher beiseite gelegt für die dynamische Zuordnung. Im Gegensatz zu dem Stapel, es gibt keine durchgesetzte Muster, um die Allokation und Freigabe von Blöcken aus dem heap; Sie können reservieren eines Blockes jederzeit und kostenlos zu jeder Zeit. Dies macht es viel schwieriger zu verfolgen, welche Teile des heap zugewiesen werden oder frei zu einem bestimmten Zeitpunkt; es gibt viele custom-heap-allocators zur Optimierung der heap Leistung für verschiedene Nutzungsmuster.
Jeder thread bekommt einen Stapel, während es in der Regel nur ein heap für die Anwendung (obwohl es nicht ungewöhnlich, dass mehrere heaps für die verschiedenen Arten der Zuweisung).
Beantworten Ihre Fragen direkt:
Das OS reserviert, wird der Stapel für jedes system-level-thread, wenn der thread erstellt wird. In der Regel das OS ist als die Sprache, die Laufzeitumgebung, um die Allokation der heap für die Anwendung.
Dem Stapel wird an einem Faden, so dass, wenn der thread beendet wird, wird der stack zurückgefordert. Der heap ist in der Regel reserviert, die beim Start der Anwendung von der Laufzeitumgebung und wird zurückgefordert, wenn die Anwendung (technisch-Prozess) beendet.
Die Größe des stack wird gesetzt, wenn ein thread erstellt wird. Die Größe des Heaps festgelegt ist, beim starten der Anwendung, kann aber wachsen, wenn Platz benötigt wird (die Zuweisung Anfragen mehr Arbeitsspeicher vom Betriebssystem).
Dem stack ist schneller, da der Zugriff Muster macht es sehr einfach zu reservieren und freigeben von Speicher (ein pointer/integer ist einfach inkrementiert oder dekrementiert), während der heap ist sehr viel komplexer, Buchhaltung betroffen sind, zuordnen oder aufheben der Zuordnung. Auch, jedes byte in den stack neigt dazu, wiederverwendet werden sehr Häufig was bedeutet, dass es tendenziell zugeordnet, um den Prozessor-cache, so dass es sehr schnell. Ein weiterer performance-Treffer für den Haufen, der Haufen, da meist eine Globale Ressource, in der Regel hat die multi-threading-sicher, d.h. jede Zuweisung und-Freigabe werden muss - in der Regel - synchronisiert mit "alle" anderen heap-Zugriffe im Programm.
Eine klare demonstration:
Bild Quelle: vikashazrati.wordpress.com
Ich bin wirklich verwirrt über das Diagramm am Ende. Ich dachte, ich habe es bis ich sah, dass Bild.
der Prozessor führt Instruktionen, die mit oder ohne os. Ein Beispiel nah an meinem Herzen ist der SNES, das hatte keine API-Aufrufe, kein Betriebssystem wie wir es heute kennen - aber es hatte einen Stapel. Die Zuweisung auf eine stack-addition und Subtraktion auf diese Systeme und das ist in Ordnung für die Variablen zerstört, wenn Sie geholt werden, von der Rückkehr aus der Funktion, die Sie erstellt, sondern kontrastieren, die, sagen wir, einem Konstruktor, von denen sich das Ergebnis nicht einfach weggeworfen werden. Dafür brauchen wir die Haufen, die nicht gebunden zu rufen und zurück. Die meisten OS haben-APIs ein heap, keinen Grund, es zu tun auf Ihre eigenen
"stack ist die Erinnerung beiseite als scratch space". Cool. Aber wo ist es tatsächlich "beiseite" in Bezug auf die Java-Speicher-Struktur?? Ist es Heap-Speicher/Non-heap-Speicher/Andere (Java-Speicher-Struktur als pro betsol.com/2017/06/... )
Java-Laufzeit als bytecode-interpreter, fügt eine weitere Ebene der Virtualisierung, also das, was Sie bezeichnet, ist nur Java-Anwendung Sicht. Aus der Sicht des Betriebssystems all das ist nur ein Haufen, in dem sich die Java-runtime-Prozess weist einige von seinem Platz als "non-heap" - Speicher für den bytecode verarbeitet. Rest der OS-Ebene heap als application-level heap-Objekt, wo die Daten gespeichert sind.
InformationsquelleAutor Jeff Hill
Stack:
Heap:
delete
,delete[]
oderfree
.new
odermalloc
bzw.Beispiel:
Es ist ein verbreiteter Irrtum, dass die
C
Sprache, definiert durch dieC99
Sprache standard (verfügbar unter open-std.org/JTC1/SC22/WG14/www/docs/n1256.pdf ), erfordert eine "stack". In der Tat, das Wort "stack" nicht erscheinen sogar in der Norm. Diese Antworten Aussagen wrt/ zuC
's stack-Nutzung sind wahr im Allgemeinen, aber ist in keiner Weise erforderlich, die durch die Sprache. Siehe knosof.co.uk/cbook/cbook.html für mehr info, und insbesondere, wieC
implementiert ist, auf ungerade-ball-Architekturen wie z.B. en.wikipedia.org/wiki/Burroughs_large_systemsSie sollte erklären, warum buffer[] und der pBuffer Zeiger werden auf dem Stapel erzeugt und warum pBuffer die Daten auf dem heap erstellt. Ich denke, dass einige ppl verwechselt werden könnte, durch Ihre Antwort, wie Sie vielleicht denken, das Programm ist speziell anweisen, dass der Speicher zugewiesen werden, auf den stack vs heap-aber dies ist nicht der Fall. Ist es, weil der Puffer ist ein Werttyp, während pBuffer ist ein Verweis geben?
Nein, ein Zeiger eine Adresse und es kann etwas zeigen auf dem heap oder dem stack gleich. new, malloc, und einige andere Funktionen wie malloc allokieren auf dem heap und Rückgabe der Adresse der Speicher reserviert wurde. Warum würden Sie wollen, reservieren Sie auf dem heap? So, dass Ihr Gedächtnis nicht mehr gültig und werden dann freigelassen, bis Sie es wollen.
"Verantwortlich für memory leaks" - Heaps sind nicht verantwortlich für memory leaks! Faul/Vergesslich/ex-java-Entwickler/Coder, die sich mit dont give a crap sind!
InformationsquelleAutor Brian R. Bondy
Der wichtigste Punkt ist, dass heap und stack sind generische Begriffe für die Möglichkeiten, die in dem Speicher zugeordnet werden kann. Sie umgesetzt werden können in viele verschiedene Möglichkeiten, und die Nutzungsbedingungen gelten für die grundlegenden Konzepte.
In einem Stapel von Elementen, Elemente sitzen oben auf dem anderen in der Reihenfolge, wie Sie platziert waren es, und Sie können nur entfernen Sie die oberen (ohne Sturz das ganze über).
Die Einfachheit von einem Stapel ist, dass Sie nicht brauchen, um zu erhalten eine Tabelle mit einem Eintrag für jeden Abschnitt zugewiesenen Speicher; der einzige Staat Informationen, die Sie brauchen, ist ein einzelner Zeiger auf das Ende des stack. Zum reservieren und freigeben, die Sie nur Inkrementieren und Dekrementieren, die einzelnen Zeiger. Hinweis: ein Stapel kann manchmal umgesetzt werden, beginnen Sie oben von einem Abschnitt des Speichers und zu verlängern, nach unten anstatt nach oben wächst.
In einem Haufen, es gibt keine bestimmte Reihenfolge, um die Art und Weise Elemente platziert werden. Erreichen Sie in und entfernen von Elementen in beliebiger Reihenfolge, denn es gibt kein klares 'top' Position.
Heap erfordert die Aufrechterhaltung eines vollständigen Datensatzes, was Speicher reserviert ist und was nicht, sowie einige overhead-Wartung, die Fragmentierung zu verringern, finden zusammenhängenden memory-Segmente groß genug, um die angeforderte Größe, und so weiter. Speicher kann freigegeben ist, jederzeit verlassen freien Raum. Manchmal ist ein memory-allocator wird Wartungsaufgaben wie Defragmentierung Speicher durch verschieben von zugeordneten Speicher um, oder Müll sammeln - die Ermittlung der Laufzeit beim Arbeitsspeicher ist nicht mehr in Umfang und freigeben.
Diese Bilder sollten tun, einen ziemlich guten job zu beschreiben die zwei Möglichkeiten der Zuweisung und Freigabe von Speicher in einen stack und einen heap. Yum!
Inwieweit sind Sie gesteuert durch das Betriebssystem oder die Sprache der Laufzeit?
Wie bereits erwähnt, heap-und stack sind die Allgemeinen Bedingungen realisiert werden können, in vielerlei Hinsicht. Computer-Programme haben in der Regel ein stack genannt call-stack, die speichert Informationen, die relevant für die aktuelle Funktion, wie z.B. einen Zeiger zu welcher Funktion es hieß aus, und alle lokalen Variablen. Da Funktionen andere Funktionen aufrufen, und dann die Rückkehr, der stack wächst und schrumpft, um Informationen aus den Funktionen weiter unten im Aufruf-stack. Ein Programm nicht wirklich runtime Kontrolle über es; es ist bestimmt durch die Programmiersprache, Betriebssystem und sogar die system-Architektur.
Ein heap ist ein allgemeiner Begriff für alle Speicher wird dynamisch zugewiesen und zufällig; d.h. nicht in Ordnung. Der Speicher ist in der Regel der Zuweisung durch die OS, die mit der Anwendung aufrufen von API-Funktionen zu tun, diese Zuordnung. Es ist ein gutes Stück der Verwaltungsaufwand in der Verwaltung von dynamisch allozierten Speicher, die in der Regel behandelt durch die OS.
Was ist Ihr Anwendungsbereich?
Den call-stack ist so ein low-level-Konzept, dass es nicht beziehen sich auf "Umfang" im Sinne von Programmierung. Wenn Sie zerlegen einige code, den Sie sehen, relative Mauszeiger-Stil Verweise auf Teile des Stapels, aber so weit als einer Sprache auf höherer Ebene ist betroffen, die Sprache schreibt seine eigenen Regeln, die in den Anwendungsbereich. Ein wichtiger Aspekt auf einem Stapel, jedoch, ist, dass, sobald eine Funktion gibt, alles lokale auf, die Funktion ist sofort befreit vom Stapel. Das funktioniert so, wie du erwartest, dass es Arbeit gegeben, wie Sie Ihre Programmier-Sprachen arbeiten. In einem Haufen, es ist auch schwer zu definieren. Der Umfang ist, was auch immer ausgesetzt ist, von der OS, aber Ihre Programmiersprache wahrscheinlich fügt seine Regeln darüber, was ein "Rahmen" ist in Ihrer Anwendung. Die Prozessor-Architektur und das Betriebssystem verwenden, virtuelle Adressierung, die den Prozessor übersetzt zu physischen Adressen, und es gibt Seitenfehler usw. Sie verfolgen welche Seiten gehören die Anwendungen. Man kann nie wirklich brauchen, um über diese, obwohl, weil Sie nur verwenden, was Methode Ihre Programmiersprache verwendet, um die Zuweisung und Freigabe von Speicher, und Fehler prüfen (wenn der Verwendungszweck/die Befreiung aus einem beliebigen Grund fehlschlägt).
Was bestimmt die Größe eines jeden von Ihnen?
Wieder, es hängt von der Sprache, compiler, Betriebssystem und die Architektur. Ein Stapel wird in der Regel im Voraus reserviert, weil es per definition sein müssen, zusammenhängenden Speicher (dazu mehr im letzten Absatz). Die Sprache, compiler oder das Betriebssystem bestimmen seine Größe. Sie nicht speichern Sie große Brocken von Daten auf dem stack, es wird also groß genug sein, dass es sollte nie vollständig verwendet, außer in Fällen von unerwünschten endlose Rekursion (daher "stack overflow") oder andere ungewöhnliche Programmierung Entscheidungen.
Ein heap ist ein allgemeiner Begriff für alles, was, die kann dynamisch zugewiesen. Je nachdem, auf welche Art und Weise man es betrachtet, es ist ständig verändernde Größe. In modernen Prozessoren und Betriebssysteme an, die genaue Art und Weise, die es funktioniert, ist sehr abstrahiert, wie auch immer, also Sie müssen normalerweise nicht zu viel sorgen darüber, wie es arbeitet tief unten, mit der Ausnahme, dass (in den Sprachen, wo es können Sie) Sie dürfen nicht verwendet Speicher, die man noch nicht zugeteilt noch oder Speicher, die Sie freigegeben haben.
Was macht man schneller?
Dem stack ist schneller, weil alle freier Speicher ist immer zusammenhängend. So eine Liste muss gepflegt werden, der alle Segmente des freien Speichers, der nur einen einzelnen Zeiger auf die aktuelle Spitze des Stacks. Compiler in der Regel speichern diese Zeiger in einer speziellen, schnell registrieren für diesen Zweck. Was mehr ist, können nachfolgende Operationen auf einem stack sind in der Regel konzentrierte sich in den sehr nahe gelegenen Bereiche des Arbeitsspeichers, die auf einem sehr niedrigen Niveau ist gut für die Optimierung durch den Prozessor mit on-die-caches.
Diese Antwort enthält einen großen Fehler. Statische Variablen werden nicht auf dem Stapel reserviert. Siehe meine Antwort [link] stackoverflow.com/a/13326916/1763801 für die Klarstellung. Sie sind gleichzusetzen "automatische" Variablen mit "static" - Variablen, aber Sie sind nicht alle gleich
Speziell, sagen Sie "statisch zugeordnet lokale Variablen" auf dem Stapel reserviert. Eigentlich sind Sie zugeordnet sind, im Daten-segment. Nur automatisch zugewiesenen Variablen (für die meisten, aber nicht alle lokalen Variablen und auch Dinge wie die Funktion Parameter übergeben, by value anstatt by reference) sind auf dem Stapel reserviert.
Ich habe gerade realisiert das du Recht hast - in C, statische Allokation ist seine eigene Sache eher als ein Begriff für alles, was nicht dynamic. Ich habe bearbeitet meine Antwort, danke.
Es ist nicht nur C. Java, Pascal, Python und viele andere, alle haben die Begriffe statische versus automatische versus dynamische Allokation. Zu sagen "statische Zuordnung" bedeutet, dass die gleiche Sache, einfach überall. In keiner Sprache ist die statische Zuordnung bedeutet "nicht dynamisch". Sie möchten der Begriff "automatische" Zuweisung für das, was Sie beschreiben (D. H. die Dinge, die auf dem stack).
InformationsquelleAutor thomasrutter
(Habe ich verschoben, diese Antwort aus einer anderen Frage war mehr oder weniger ein dupe von diesem.)
Die Antwort auf Ihre Frage ist, ist die Implementierung spezifisch und variieren in den verschiedenen Compiler und Prozessor-Architekturen. Allerdings ist hier eine vereinfachte Erklärung.
Heap
new
odermalloc
) zufrieden sind von der Erstellung eines geeigneten block von einem der freien Blöcke. Dies erfordert eine Aktualisierung der Liste der Blöcke auf dem heap. Diese meta-Informationen über die Blöcke auf dem heap gespeichert auf dem heap oft in einem kleinen Bereich direkt vor jedem block.Der stack
instruction pointer auf die Adresse der Funktion, die aufgerufen wird. Später, wenn die Funktion zurückgibt, die alten befehlszeiger tauchte aus dem Stapel und wird die Ausführung auf den code nach dem Aufruf der Funktion.
Nein, activation records für Funktionen (D. H. lokalen oder automatische Variablen) zugeordnet sind, die auf dem stack, der verwendet wird, nicht nur zur Speicherung dieser Variablen, sondern auch zu verfolgen, verschachtelte Funktionsaufrufe.
Wie der heap verwaltet wird, ist wirklich bis auf die Laufzeit-Umgebung. C verwendet
malloc
und C++, verwendetnew
aber auch viele andere Sprachen haben garbage collection.Jedoch der stack ist eine low-level-Features eng mit der Prozessor-Architektur. Wachsen die Haufen, wenn es nicht genügend Speicherplatz ist nicht allzu schwer, da kann es umgesetzt werden in die Bibliothek nennen, die Verarbeitung des heap. Allerdings wächst der stack ist oft unmöglich, da die stack-overflow nur entdeckt wird, wenn es zu spät ist; und abschalten der thread der Ausführung ist die einzig praktikable option.
Jeder Typ der Referenz ist die Zusammensetzung von Wert-Typen(int, string, etc.). So wie es gesagt wird, dass Werttypen gespeichert werden im stack als wie funktioniert es, wenn Sie den Typ der Referenz.
Diese Antwort war die beste meiner Meinung nach, weil es mir geholfen zu verstehen, was eine return-Anweisung wirklich ist und wie es sich auf das "return-Adresse", die ich über jeden jetzt und dann, was es bedeutet, eine push-Funktion auf dem stack, und warum Funktionen geschoben werden, auf den Stapel. Super Antwort!
Dies ist die beste meiner Meinung nach, nämlich zu erwähnen, dass der heap/stack sehr Umsetzung-spezifisch. Die anderen Antworten gehen von einem viel alles über die Sprache und die Umgebung/OS. +1
Was meinst du mit "Der code in der Funktion ist dann in der Lage zu navigieren, bis Sie den Stapel aus dem aktuellen stack-pointer auf die Suche nach diesen Werten." ? Können Sie etwas näher erläutern, bitte?
InformationsquelleAutor Martin Liversage
In der folgende C# - code
Hier ist, wie der Speicher verwaltet wird
Local Variables
, die müssen nur so lange, wie der Funktions-Aufruf gehen in den Stapel. Der heap wird für Variablen verwendet, deren Leben wir nicht wirklich im Vorfeld wissen, aber wir erwarten, dass Sie eine Weile dauern. In den meisten Sprachen ist es wichtig, dass wir wissen, dass zur compile-Zeit, wie groß eine variable ist, wenn wir wollen, speichern Sie es auf dem Stapel.Objekte (die in der Größe variieren, so aktualisieren wir Ihnen) gehen über den Haufen, weil wir nicht wissen, zum Zeitpunkt der Erstellung, wie lange Sie noch dauern wird. In vielen Sprachen wird der Haufen Müll gesammelt, um Gegenstände zu finden (wie der cls1 Objekt), die haben nicht mehr alle Referenzen.
In Java, die meisten Objekte gehen direkt in den heap. In Sprachen wie C /C++ Strukturen und Klassen können, bleiben oft auf den Stapel, wenn Sie nicht den Umgang mit Zeigern.
Mehr Informationen finden Sie hier:
Der Unterschied zwischen stack und heap-Speicher-Zuweisung « timmurphy.org
und hier:
Erstellen von Objekten auf dem Stack und Heap
Dieser Artikel ist die Quelle Bild oben: Sechs wichtige .NET-Konzepte: Stack, heap, Wertetypen, Referenztypen-boxing und unboxing - CodeProject
aber bewusst sein, es enthält einige Ungenauigkeiten.
Ich habe nicht gesagt, Sie waren statisch Variablen. Ich sagte, dass int und cls1 sind statisch items. Ihre Speicher statisch zugewiesen, und Sie gehen deshalb auf den Stapel. Dies ist im Gegensatz zu einem Objekt benötigt dynamische Speicherverwaltung, die geht damit über den Haufen.
Ich zitiere "Statische Elemente... gehen auf den Stapel". Dies ist nur flat-out falsch. Statische Gegenstände gehen in das Daten-segment, automatische Gegenstände gehen auf den Stapel.
Auch wer geschrieben hat, dass codeproject Artikel nicht weiß, was er redet. Er sagt z.B., dass "primitiven Bedürfnisse static type memory" das ist völlig unwahr. Nichts hält Sie von der Zuweisung von primitiven in der heap dynamisch, schreib einfach etwas wie "int array[] = new int[num]" und voila, primitive dynamisch zugewiesen .NET. Das ist nur eine von mehreren Ungenauigkeiten.
Ich bearbeitet Ihren Beitrag, weil Sie haben ernsthafte technische Fehler, über das, was geht in den stack-und heap.
InformationsquelleAutor Snowcrash
Der Stack
Beim Aufruf einer Funktion werden die Argumente an die Funktion plus einige andere overhead wird auf den Stapel gelegt. Einige Infos (wie, wo zu gehen, bei Rückgabe) wird auch dort gespeichert.
Wenn Sie deklarieren eine variable innerhalb der Funktion, die variable ist auch auf dem Stapel reserviert.
Freigeben der stack ist ziemlich einfach, weil Sie immer freigeben in umgekehrter Reihenfolge, in dem Sie reservieren. Stapel Sachen Hinzugefügt, wie Sie Funktionen eingeben, werden die entsprechenden Daten gelöscht, wenn Sie verlassen. Dies bedeutet, dass Sie neigen dazu, zu bleiben in einem kleinen Bereich auf dem stack, es sei denn, Sie rufen Sie eine Menge Funktionen, die zum Aufruf viele andere Funktionen (oder erstellen Sie eine rekursive Lösung).
Heap
Der heap ist ein generischer name für, wo Sie die Daten, die Sie spontan erstellen. Wenn Sie nicht wissen, wie viele Raumschiffe, die Ihr Programm erstellen, werden Sie wahrscheinlich verwenden Sie die neue (oder malloc oder gleichwertig) - operator zum erstellen jedes Raumschiff. Diese Zuordnung geht, zu bleiben, um für eine Weile, so ist es wahrscheinlich, wir werden frei, die Dinge in einer anderen Reihenfolge als wir Sie geschaffen haben.
So, der Haufen ist viel komplexer, weil es am Ende werden Speicherbereiche, die nicht interleaved mit Stücken, die - Speicher wird fragmentiert. Finden kostenlos Erinnerung an die Größe, die Sie brauchen, ist ein schwieriges problem. Dies ist der Grund, warum der heap sollte vermieden werden (obwohl es immer noch oft verwendet).
Umsetzung
Implementierung von stack und heap in der Regel nach unten, um die Laufzeit /OS. Oft Spiele und andere Anwendungen, die Leistung Kritischer erstellen Sie Ihre eigenen memory-Lösungen, die greifen sich ein großes Stück von Speicher aus dem heap und dann austeilen intern zu vermeiden, sich auf die OS-Speicher.
Dies ist nur dann sinnvoll, wenn der Speicherverbrauch ist völlig Verschieden von der norm - ich.e für Spiele, wo man laden eines Levels in einem großen Betrieb und kann chuck das ganze entfernt in einem riesigen Betrieb.
Stelle im Speicher
Dies ist weniger relevant, als Sie denken, weil einer Technologie namens Virtueller Speicher was macht das Programm denken, dass Sie haben Zugriff auf eine bestimmte Adresse, wo die physikalischen Daten woanders (auch auf der Festplatte!). Die Adressen erhalten Sie für den stack sind in aufsteigender Reihenfolge Ihrer aufrufstruktur wird tiefer. Die Adressen der heap un-vorhersehbar (ich.e Umsetzung spezifisch) und ehrlich gesagt auch nicht wichtig.
Wenn du den stack oder auf dem heap, verwenden Sie die Stapel. Wenn Sie nicht verwenden können, den stack, der eigentlich keine Wahl hat. Ich benutze beide sehr viel, und natürlich mit std::vector oder ähnliches trifft den heap. Für einen Anfänger, vermeiden Sie die heap-weil der stack ist einfach so einfach!!!!
Wenn Ihre Sprache nicht implementieren, garbage collection, Smart-Pointer (Seporately zugewiesenen Objekte, die wrap-around-Zeiger, die Referenz-Zählung für die dynamisch zugewiesenen Speicher) sind eng mit der "garbage collection" eine anständige Art der Verwaltung des heap in einer sicheren und leckagefreien Art und Weise. Sie sind umgesetzt in verschiedenen frameworks, sind aber auch nicht all zu schwer zu implementieren für Ihre eigenen Programme.
"Aus diesem Grund heap sollte vermieden werden (obwohl es immer noch oft verwendet)." Ich bin mir nicht sicher, was dies bedeutet praktisch, vor allem, wie Speicher verwaltet wird anders als in vielen high-level-Sprachen. Da diese Frage markiert ist sprachunabhängig, ich würde sagen, dies insbesondere Kommentar/line ist schlecht platziert und nicht anwendbar.
Guter Punkt @JonnoHampson - Während Sie einen gültigen Punkt, würde ich argumentieren, dass, wenn Sie arbeiten in einer "Hochsprache" mit einem GC werden Sie wahrscheinlich egal, über die memory-allocation-Mechanismen an alle - und so gar nicht um das, was die stack-und heap sind.
InformationsquelleAutor Tom Leys
Klären, diese Antwort hat falsche Informationen (thomas befestigt seine Antwort nach Kommentaren, cool 🙂 ). Andere Antworten nur vermeiden erklären, was die statische Zuordnung bedeutet. Also werde ich die drei wichtigsten Formen der Zuweisung und wie Sie in der Regel beziehen sich auf den heap, stack und Daten-segment weiter unten. Ich werde auch zeigen einige Beispiele sowohl in C/C++ und Python, um Menschen helfen zu verstehen.
"Statische" (AKA statisch reservierte) Variablen werden nicht auf dem Stapel reserviert. Nicht davon ausgehen, so viele Menschen tun, nur weil Sie "statisch" klingt viel wie "Stapel". Sie tatsächlich existieren, weder auf dem stack noch die heap. Die sind Teil von dem, was heißt die Daten-segment.
Jedoch ist es im Allgemeinen besser zu berücksichtigen "Umfang" und "Lebensdauer" statt "stack" und "heap".
Geltungsbereich bezieht sich auf das, was Teile des Codes können Sie den Zugriff auf eine variable. Generell denken wir an lokalen Bereich (kann nur zugegriffen werden, die von der aktuellen Funktion) versus globalen Bereich (zugegriffen werden kann, überall) obwohl Rahmen viel komplexer.
Lebensdauer bezieht sich auf, wenn eine variable zugeordnet ist, und freigegeben ist, während der Ausführung des Programms. Normalerweise denken wir, dass der statische Zuordnung (variable beibehalten wird, die über die gesamte Dauer des Programms, so dass es nützlich für die Speicherung von gleichen Informationen über mehrere Funktionsaufrufe) versus automatische Zuordnung (variable nur weiterhin über einen einzigen Aufruf einer Funktion, so dass es nützlich für die Speicherung von Informationen, die nur in Ihrer Funktion und können verworfen werden, sobald Sie fertig sind) im Vergleich zu dynamische Zuordnung (Variablen, deren Dauer definiert ist, zur Laufzeit, statt compile-Zeit, wie z.B. statische oder automatisch).
Obwohl die meisten Compiler und-Interpreter implementieren Sie dieses Verhalten auch in Bezug auf die Verwendung von stacks, heaps, etc., ein compiler kann manchmal brechen diese Konventionen, wenn es will, solange das Verhalten korrekt ist. Zum Beispiel durch die Optimierung eine lokale variable kann nur existieren, in einem register oder vollständig entfernt werden, auch wenn die meisten lokale Variablen existieren, die in den Stapel. Wie hat gewesen wies darauf hin, in ein paar Kommentare, Sie sind frei, implementieren Sie einen compiler, der nicht einmal mit einem Stapel oder Haufen, sondern einige andere Speicher-Mechanismen (selten getan, da Stapel und Haufen sind großartig für diese).
Werde ich Ihnen einige einfache kommentierten C-code zu veranschaulichen. Der beste Weg zu lernen ist, führen Sie ein Programm unter einem debugger und beobachten Sie das Verhalten. Wenn Sie es vorziehen, zu Lesen, python, überspringen, um das Ende der Antwort 🙂
Ein besonders ergreifendes Beispiel dafür, warum es wichtig ist zu unterscheiden zwischen Lebensdauer und Reichweite ist, dass eine variable kann lokal aber statische Lebensdauer - zum Beispiel, "someLocalStaticVariable" in dem Beispielcode oben. Solche Variablen können unsere gemeinsamen, aber informellen Benennung Gewohnheiten sehr verwirrend. Zum Beispiel, wenn wir sagen "lokalen" meinen wir meist "lokal gültigen automatisch zugewiesene variable" und wenn wir sagen, dass wir global in der Regel bedeuten, "Global statisch zugewiesene variable". Leider, wenn es um Dinge wie "Datei-Gültigkeitsbereich statisch allokierten Variablen" viele Leute sagen... "huh???".
Einige der syntax Entscheidungen in C/C++ verschärfen dieses problem - zum Beispiel, viele Leute denken, Globale Variablen sind nicht "statisch", weil die syntax unten.
Beachten Sie, dass putting das Schlüsselwort "static" in der Deklaration oben verhindert var2 aus mit einem globalen Gültigkeitsbereich. Dennoch, die global var1 hat die statische Zuordnung. Dies ist nicht intuitiv! Aus diesem Grund ich versuchen, verwenden Sie niemals das Wort "static" bei der Beschreibung von Umfang und stattdessen etwas sagen wie "Datei" oder "Datei " eingeschränkten" Umfang. Doch viele Menschen verwenden den Begriff "statisch" oder "static scope" zu beschreiben, eine variable, die nur zugegriffen werden kann, aus einer code-Datei. Im Rahmen der Lebensdauer, "static" immer bedeutet, dass die variable zugeordnet wird, die bei Programm-start und freigegeben, wenn das Programm beendet wird.
Einige Leute denken, der diese Konzepte als C/C++ - spezifisch. Sie sind es nicht. Zum Beispiel die Python-Beispiel unten zeigt alle drei Arten der Vergabe (es gibt einige subtile Unterschiede in interpretierten Sprachen, die ich nicht hier).
PostScript
haben mehrere Stapel, aber einen "Haufen", der verhält sich wie ein stack.Das macht alles Sinn. Ich definiert als Umfang ", was Teile des Codes können access eine variable" (und denke, dies ist die meisten standard-definition), so dass ich denke, dass wir uns einig 🙂
Ich würde bezüglich der "scope" eines variable wie wird begrenzt durch Zeit sowie Raum. Eine variable in class-Objekt scope ist erforderlich, um zu halten Ihren Wert, solange das Objekt existiert. Eine variable innerhalb eines Ausführungs-Kontext-scope ist erforderlich, um zu halten Ihren Wert, solange die Ausführung bleibt in diesem Zusammenhang. Eine statische variable Deklaration erstellt ein id, dessen Geltungsbereich begrenzt wird, um den aktuellen block, die verbunden ist, um eine variable, deren Umfang ist unbegrenzt.
Das ist, warum ich das Wort Leben, das ist, wie ich Begriff, was Sie Zeit nennen, Umfang. Es verringert die Notwendigkeit zu überladen mit dem Wort "Umfang" mit so vielen Bedeutungen. Soweit ich das beurteilen kann, scheint es nicht zu sein, insgesamt Konsens über die genauen Definitionen aber auch unter den kanonischen Quellen. Meine Terminologie ist teilweise gezeichnet von K&R und teilweise von der vorherrschenden Verwendung bei der ersten CS-Abteilung, die ich studierte/lehrte an. Immer gut zu hören, ein weiteres informiert-Ansicht.
Sie müssen Spaß machen. kann Sie wirklich definieren statische Variablen innerhalb einer Funktion ?
InformationsquelleAutor
Anderen beantwortet habe die breiten Striche ziemlich gut, also ich werde werfen in ein paar details.
Stack und heap werden, brauchen nicht im singular. Eine gemeinsame situation, in der Sie mehr als einen Stapel, wenn Sie mehr als ein thread in einem Prozess. In diesem Fall ist jeder thread hat seinen eigenen stack. Sie können auch mehr als ein Haufen, zum Beispiel einige DLL-Konfigurationen können dazu führen, dass verschiedene DLLs die Zuweisung von verschiedenen Haufen, das ist, warum es generell eine schlechte Idee Speicher freigegeben wird, der durch eine andere Bibliothek.
In C können Sie den Vorteil der Variablen Länge der Zuteilung durch den Einsatz von alloca, die reserviert auf dem stack, im Gegensatz zu alloc, die reserviert auf dem heap. Dieser Speicher wird nicht überleben return-Anweisung, aber es ist nützlich, für einen scratch-Puffer.
Einen riesigen temporären Puffer auf Windows, die Sie verwenden nicht viel, ist nicht frei. Dies ist, weil der compiler erzeugt einen stack-probe-Schleife, die jedesmal aufgerufen, wenn die Funktion eingegeben wird, stellen Sie sicher, dass der Stapel vorhanden ist (da Windows verwendet eine einzelne Seite schützen am Ende Ihren stack zu erkennen, wenn es Sie braucht, um zu wachsen die Stapel. Wenn Sie den Zugriff auf den Speicher mehr als eine Seite aus dem Ende des Stapels, Sie wird Abstürzen). Beispiel:
Wie tragbar ist
alloca
?es ist nicht POSIX, Portabilität nicht gewährleistet.
InformationsquelleAutor Don Neufeld
Andere haben direkt Ihre Frage beantwortet, aber wenn man versucht zu verstehen, stack und heap, denke ich, ist es hilfreich zu betrachten, das Speicher-layout von einer traditionellen UNIX-Prozess (ohne Gewinde und
mmap()
-basierte allocators). Die Memory-Management-Glossar web-Seite hat eine Abbildung dieses memory-layout.Stack und heap sind traditionell befindet sich an den gegenüberliegenden enden der Prozess des virtuellen Adressraums. Der stack wächst automatisch, wenn Sie aufgerufen werden, bis zu einer Größe gesetzt, die durch den kernel (das kann angepasst werden, mit
setrlimit(RLIMIT_STACK, ...)
). Der heap wächst, wenn die arbeitsspeicherzuweisung ruft diebrk()
odersbrk()
system call, mapping-weitere Seiten von physikalischen Speicher, in den Prozess der virtuellen Adressraums.In Systemen ohne virtuellen Speicher, wie einige embedded-Systeme, die gleichen grundlegenden layout oft gilt, es sei denn der stack und heap sind eine Feste Größe. Jedoch, in anderen embedded-Systemen (wie solche, die auf Microchip PIC-mikrocontroller), die Programm-stack ist ein separater block von Speicher ist nicht adressierbar Daten Bewegung Anweisungen, und können nur geändert werden, oder Lesen Sie indirekt über Programm-Ablauf-Anweisungen (call, return, usw.). Andere Architekturen, wie Intel Itanium-Prozessoren, haben mehrere stacks. In diesem Sinne, ist der stack ein element von der CPU-Architektur.
InformationsquelleAutor bk1e
Der Stapel ist ein Teil des Speichers, der manipuliert werden kann, über mehrere der wichtigsten Assembler-Anweisungen, wie z.B. " pop "(entfernen und zurückgeben eines Werts aus dem Stapel) und "push" (push einen Wert auf dem stack), aber auch call (Aufruf Unterprogramm - dabei schiebt sich die Adresse zurück auf den Stapel) und return (Rückkehr aus einem Unterprogramm - daraufhin wird die Adresse vom stack und springt zu ihm). Es ist der Bereich des Speichers, unterhalb der stack-pointer-register, die gesetzt werden können, wie gebraucht. Der stack wird auch für die übergabe von Argumenten an Unterprogramme, und auch für die Erhaltung der Werte in die Register vor dem Aufruf von Unterprogrammen.
Heap ein Teil des Speichers gegeben ist eine Anwendung, die vom Betriebssystem, in der Regel durch einen Systemaufruf wie malloc. Auf moderne Betriebssysteme dieser Speicher ist eine Reihe von Seiten, die nur der aufrufende Prozess Zugriff hat.
Die Größe des Stacks zur Laufzeit festgelegt und in der Regel nicht wachsen, nach dem das Programm startet. In einem C-Programm den stack muss groß genug für jede deklarierte variable in jeder Funktion. Der heap wird dynamisch wachsen wie benötigt, aber das Betriebssystem ist letztlich, die den Aufruf (es wird oft wachsen die Haufen von mehr als den angeforderten Wert von malloc, so dass zumindest einige künftige mallocs nicht brauchen, zurück zu gehen, um den kernel zu bekommen mehr Arbeitsspeicher. Dieses Verhalten ist oft anpassbar)
Weil Sie haben zugeteilt dem Stapel, bevor Sie das Programm starten, werden Sie nie brauchen, um malloc, bevor Sie Sie verwenden den stack, also einen leichten Vorteil gibt. In der Praxis ist es sehr schwer, vorherzusagen, was schnell und was langsam in modernen Betriebssystemen, die virtuellen Speicher-Subsystemen, weil, wie die Seiten umgesetzt sind und wo Sie gespeichert sind, ist eine Implementierung detail.
InformationsquelleAutor Daniel Papasian
Ich denke, viele andere Menschen gegeben haben, die Sie meistens richtige Antworten auf diese Frage.
Ein detail wurde übersehen, ist jedoch, dass der "Haufen" sollte in der Tat wohl als "frei speichern". Der Grund für diese Unterscheidung ist, dass die original-free-Shop wurde umgesetzt mit einer Daten-Struktur, bekannt als eine "binomial heap". Aus diesem Grund, die Zuweisung von frühen Implementierungen von malloc()/free() wurde die Zuteilung aus einem heap. Jedoch, in dieser modernen Tag, die meisten free-Shops umgesetzt werden, mit sehr aufwendigen Datenstrukturen, die sich nicht binomial-heaps.
C
Sprache. Dies ist ein weit verbreiteter Irrglaube, aber es ist die (mit Abstand) Dominieren Paradigma für die UmsetzungC99 6.2.4 automatic storage duration objects
(Variablen). In der Tat, das Wort "stack" gar nicht angezeigt in derC99
Sprache standard: open-std.org/JTC1/SC22/WG14/www/docs/n1256.pdf[@Heath] ich habe einen kleinen Kommentar zu Ihrer Antwort. Werfen Sie einen Blick auf die akzeptierte Antwort auf diese Frage. Er sagt, dass die free store wahrscheinlich ist dasselbe wie heap, aber nicht notwendigerweise ist.
InformationsquelleAutor
Was ist ein stack?
Ein stack ist ein Stapel von Objekten, in der Regel eine, die ordentlich angeordnet.
Was ist ein heap?
Einem Haufen ist eine unordentliche Sammlung von Dingen aufgestapelt willkürlich.
Beide zusammen
, Welche schneller ist – die-stack oder auf dem heap? Und warum?
Für Leute die neu in die Programmierung sind, ist es wahrscheinlich eine gute Idee, mit dem stack, da es einfacher ist.
Weil der stack zu klein ist, würden Sie wollen, um es zu verwenden, wenn Sie genau wissen, wie viel Speicher Sie benötigen für Ihre Daten, oder wenn Sie wissen, die Größe Ihrer Daten ist sehr klein.
Es ist besser, um die heap-wenn Sie wissen, dass Sie benötigen viel Speicher für Ihre Daten, oder Sie sind einfach nicht sicher, wie viel Arbeitsspeicher Sie benötigen (wie bei einem dynamischen array).
Java-Memory-Modell
Den stack ist der Bereich des Speichers, in dem lokale Variablen (einschließlich der Methodenparameter) gespeichert sind. Wenn es um Objekt-Variablen, diese sind nur Referenzen (Zeiger) auf die eigentlichen Objekte auf dem heap.
Jedes mal, wenn ein Objekt instanziiert wird, ein Stück des heap-Speicher beiseite zu halten, die Daten (Zustand) des Objekts. Da die Objekte können andere Objekte enthalten, werden einige dieser Daten können in der Tat halten Referenzen auf verschachtelte Objekte.
InformationsquelleAutor Shreyos Adikari
Können Sie einige interessante Dinge mit dem stack. Zum Beispiel, Sie haben Funktionen wie alloca (vorausgesetzt, Sie können vorbei an den reichlich Warnungen über seine Verwendung), das ist eine form von malloc, die speziell verwendet den Stapel nicht auf dem heap für den Speicher.
Sagte, stack-basierter Speicher-Fehler sind einige der schlimmsten, die ich erlebt habe. Wenn Sie verwenden, heap-Speicher, und Sie überschreiten die Grenzen der Ihr zugewiesenen block, Sie haben eine gute chance zur Auslösung von segment-Fehler. (Nicht 100%: deine Sperre ist übrigens zusammenhängend mit einem anderen, das Sie zuvor zugewiesen.) Aber da die erstellten Variablen auf dem stack sind immer zusammenhängend mit einander, schreiben out-of-bounds können den Wert einer anderen Variablen. Ich habe gelernt, dass, Wann immer ich das Gefühl, dass mein Programm hat aufgehört zu Gehorsam gegenüber den Gesetzen der Logik, ist es wahrscheinlich Pufferüberlauf.
alloca
? Zum Beispiel funktioniert es auf Windows? Ist es nur für Unix-ähnliche Betriebssysteme?InformationsquelleAutor Peter
Einfach, der stack wo die lokalen Variablen erzeugt. Auch, jedes mal, wenn Sie eine Unterroutine aufrufen der Programm-Zähler (Zeiger auf den nächsten Maschinenbefehl) und alle wichtigen Register, und manchmal auch die Parameter erhalten auf den stack geschoben. Dann ist jede lokale Variablen innerhalb des Unterprogramms werden auf dem Stapel abgelegt (und von dort verwendet werden). Wenn das Unterprogramm abgeschlossen ist, das Zeug wird alles tauchte wieder aus dem Stapel. Die PC-und register-Daten bekommt und legte zurück, wo es war, als es knallte, so dass Ihr Programm können gehen Sie auf Ihre fröhliche Art und Weise.
Dem heap ist der Bereich der memory-dynamische Zuweisung von Arbeitsspeicher aus (explizit "neue" oder "weisen" nennt). Es ist eine spezielle Datenstruktur, die den überblick behalten können Speicherblöcke unterschiedlicher Größe und Zuordnung status.
In "klassischen" Systemen der RAM wurde so ausgelegt, dass der stack-pointer begann bei den unteren Speicher, dem heap Zeiger begann an der Spitze, und Sie wuchsen aufeinander zu. Wenn Sie überlappen, werden Sie aus dem Arbeitsspeicher. Das funktioniert nicht mit modernen multi-threaded-Betriebssystemen, obwohl. Jeder thread hat seinen eigenen stack, und diese können erstellt werden dynamicly.
Ich sage das, weil es ist völlig bis zu dem Schriftsteller, der dem compiler/interpreter, was passiert, wenn ein Unterprogramm aufgerufen wird. Klassische Fortran-Verhalten ist nicht zu verwenden, ein stack überhaupt. Einige Sprachen unterstützen, exotische Dinge wie pass-by-name, das ist tatsächlich eine textuelle Ersetzung.
InformationsquelleAutor T.E.D.
Vom WikiAnwser.
Stack
Wenn eine Funktion oder eine Methode ruft eine weitere Funktion, die wiederum ruft eine andere Funktion, etc., die Ausführung aller dieser Funktionen bleibt angehalten, bis Sie die Letzte Funktion gibt seinen Wert zurück.
Diese Kette aufgehängt-Funktionsaufrufe stack ist, da die einzelnen Elemente im Stapel (function calls), die voneinander abhängen.
Dem Stapel ist wichtig, zu betrachten, Ausnahmebehandlung und Threads Ausführungen.
Heap
Der Haufen ist einfach nur der Arbeitsspeicher, der von Programmen zum speichern von Variablen.
Element des Heaps (Variablen), die keine Abhängigkeiten haben, die mit einander und können jederzeit aufgerufen werden, nach dem Zufallsprinzip zu jeder Zeit.
InformationsquelleAutor devXen
Stack
Heap
InformationsquelleAutor unknown
OK, einfach und in kurzen Worten, Sie bedeuten bestellt und nicht bestellt...!
Stack: In der stack-Elemente, die Dinge auf die Spitze jedes-anderen, heißt, wird schneller und effizienter verarbeitet werden!...
So gibt es immer einen index, um die spezifische Element, auch die Verarbeitung wird schneller, es ist die Beziehung zwischen den Elementen, wie gut!...
Heap: Keine Ordnung, die Verarbeitung wird langsamer und Werte sind Durcheinander, zusammen mit keine bestimmte Reihenfolge oder index... gibt es zufällig und es gibt keine Beziehung zwischen Ihnen... so dass die Ausführung und Verwendung Zeit könnte man variieren...
Ich auch das Bild unten, um zu zeigen, wie Sie Aussehen könnte:
InformationsquelleAutor Alireza
In Kurzen
Einen stack für statische Speicherzuordnung und ein heap ist für die dynamische Speicherverwaltung, die beide im computer gespeichert (RAM).
Im Detail
Der Stack
Der stack ist ein "LIFO" (last in, first out) Datenstruktur, die, verwaltet und optimiert, dass die CPU Recht eng werden. Jedes mal, wenn eine Funktion deklariert eine neue variable, es wird "vorangetrieben" auf den Stapel. Dann jedes mal, wenn eine Funktion beendet wird, werden alle Variablen auf dem Stapel abgelegt, indem Sie die Funktion freigegeben ist (das heißt, Sie werden gelöscht). Sobald eine stack-variable freigegeben wird, dass der Bereich des Speichers wird für andere stack-Variablen.
Der Vorteil bei der Verwendung der stack zum speichern von Variablen, ist, dass die Erinnerung für Sie verwaltet. Sie don ' T Speicher von hand, oder frei, sobald Sie nicht mehr benötigen. Was mehr ist, weil die CPU organisiert stack-Speicher so effizient, das Lesen von und schreiben auf stack-Variablen ist sehr schnell.
Mehr gefunden werden kann hier.
Heap
Heap ist ein Bereich im Arbeitsspeicher Ihres Computers nicht automatisch verwaltet für Sie, und ist nicht als straff geführte durch die CPU. Es ist ein free-floating-Bereich des Speichers (und größer). Reservieren von Speicher auf dem heap verwenden, müssen Sie mit malloc() oder calloc(), die built-in C-Funktionen. Sobald Sie haben, reservierten Speicher auf dem heap, Sie sind verantwortlich für die Verwendung von free() freigeben, dass der Speicher, sobald Sie nicht mehr benötigen.
Wenn Sie dies nicht tun, wird Ihr Programm, was ist bekannt als ein memory-leak. Das ist, Speicher auf dem heap wird noch beiseite gelegt werden (und nicht verfügbar sein, um andere Prozesse). Wie wir sehen werden, in dem debugging Abschnitt, dort ist ein tool namens Valgrind, dass kann Ihnen helfen, erkennen von Speicherlecks.
Anders als der stack wird der heap keine Größe Beschränkungen auf die Variablen Größe (abgesehen von den offensichtlichen körperlichen Einschränkungen von Ihrem computer). Heap-Speicher ist etwas langsamer gelesen und geschrieben, da hat man Zeiger verwenden, um Zugriff auf den Speicher auf dem heap. Wir sprechen über Zeiger kurz.
Anders als der stack-Variablen auf dem heap erstellt werden zugänglich, indem man eine Funktion überall in Ihrem Programm. Heap-Variablen sind im wesentlichen global.
Mehr gefunden werden kann hier.
Variablen zugewiesen, die auf dem stack gespeichert sind, direkt auf den Speicher und den Zugriff auf diesen Speicher ist sehr schnell, und die Zuordnung wird mit behandelt, wenn das Programm kompiliert wird. Wenn eine Funktion oder eine Methode ruft eine weitere Funktion, die wiederum ruft eine andere Funktion, etc., die Ausführung aller dieser Funktionen bleibt angehalten, bis Sie die Letzte Funktion gibt seinen Wert zurück. Der stack ist immer reserviert in einem LIFO-Reihenfolge, die die meisten vor kurzem reserviert-block wird immer der nächste block freigegeben werden. Dies macht es wirklich einfach, den überblick zu behalten-Stapel, zu befreien, einen block aus dem Stapel ist nichts mehr als eine Anpassung Zeiger.
Variablen reserviert auf dem heap haben Ihre Speicher zur Laufzeit und Zugriff auf diesen Speicher ist ein bisschen langsamer, aber die heap-Größe wird nur begrenzt durch die Größe des virtuellen Speichers. Elemente des Heaps haben keine Abhängigkeiten untereinander und können jederzeit aufgerufen werden, nach dem Zufallsprinzip zu jeder Zeit. Nehmen Sie einen block und jederzeit frei es zu jeder Zeit. Dies macht es viel schwieriger zu verfolgen, welche Teile des heap zugewiesen werden oder sich frei zu jeder Zeit gegeben.
Können Sie den Stapel, wenn Sie genau wissen, wie viel Daten, die Sie brauchen, um zu reservieren, bevor compile-Zeit, und es ist nicht zu groß. Können Sie den Haufen, wenn Sie nicht genau wissen, wie viel Daten Sie benötigen zur Laufzeit oder bei Bedarf reservieren Sie eine Menge von Daten.
In einer multi-threaded-situation, jeder thread hat seine eigene völlig unabhängige stack, aber Sie teilen sich den heap. Der stack-thread-spezifischen und der heap ist anwendungsspezifisch. Der stack ist wichtig, zu betrachten, Ausnahmebehandlung und Threads Ausführungen.
Jeder thread bekommt einen Stapel, während es in der Regel nur ein heap für die Anwendung (obwohl es nicht ungewöhnlich, dass mehrere heaps für die verschiedenen Arten der Zuweisung).
Zur Laufzeit, wenn die Applikation benötigt mehr Speicher, den es kann, Speicher in Speicher frei und wenn der stack benötigt Speicher, es können Speicher von freien Speicher allokiert Speicher für die Anwendung.
Sogar, mehr detail gegeben ist hier und hier.
Kommen Sie jetzt zu Ihre Frage Antworten.
Das OS reserviert, wird der Stapel für jedes system-level-thread, wenn der thread erstellt wird. In der Regel das OS ist als die Sprache, die Laufzeitumgebung, um die Allokation der heap für die Anwendung.
Mehr gefunden werden kann hier.
Bereits in der Spitze.
Mehr finden Sie in hier.
Die Größe des Stapels wird durch OS wenn ein thread erstellt wird. Die Größe des heap ist auf Anwendung starten, aber es kann wachsen, wenn Platz benötigt wird (die Zuweisung Anfragen mehr Arbeitsspeicher vom Betriebssystem).
Stack-Allokation ist viel schneller, weil alles, was es wirklich tut, ist, bewegen Sie den stack-pointer. Mit Speicher-pools, die Sie bekommen können eine vergleichbare Leistung aus dem heap, aber das kommt mit einer geringen Komplexität und seine eigenen Kopfschmerzen.
Auch, stack vs. heap ist nicht nur ein performance-Aspekt; darüber hinaus erfahren Sie eine Menge über die erwartete Lebensdauer der Objekte.
Details finden Sie ab hier.
InformationsquelleAutor Abrar Jahin
In den 1980er Jahren, UNIX vermehrten wie die karnickel mit großen Unternehmen Rollen Ihre eigenen.
Exxon hatte eine, ebenso wie Dutzende von Markennamen Laufe der Geschichte verloren gegangen.
Wie Speicher gelegt wurde, war im Ermessen der vielen implementors.
Einer typischen C-Programm war flach ausgebreitet in Speicher mit
die Möglichkeit zu erhöhen, durch änderung der brk () - Wert.
In der Regel, wird der HAUFEN war direkt unter diesem brk-Wert
und Erhöhung der brk-erhöht die Menge der verfügbaren heap.
Den single-STACK wurde in der Regel ein Bereich unterhalb des HEAP-das war ein Stück Erinnerung
mit nichts von Wert, bis die Spitze der nächsten festen block im Speicher.
Das nächste block war oft CODE, die überschrieben werden können, die von stack-Daten
in einer der bekanntesten hacks seiner Zeit.
Einer typischen Speicher-block wurde BSS (block null-Werte)
war versehentlich nicht genullt bei einem Hersteller anbietet.
Ein weiterer war die DATEN, die initialisiert Werte, einschließlich strings und zahlen.
Ein Dritter wurde CODE mit CRT (C-runtime), Haupt, - Funktionen und-Bibliotheken.
Dem Aufkommen virtueller Speicher in UNIX-Veränderungen, die viele der Einschränkungen.
Es gibt keinen objektiven Grund, warum diese Bausteine müssen aufeinander Folgen
oder eine Feste Größe, oder bestellt eine bestimmte Art und Weise jetzt.
Natürlich, bevor UNIX Multics, die nicht leiden unter diesen Einschränkungen.
Hier ist ein Schema zeigt einer der Speicher-layouts der ära.
InformationsquelleAutor jlettvin
stack, heap und Daten jeder Prozess im virtuellen Speicher:
InformationsquelleAutor Yousha Aleayoub
Ein paar cents: ich denke, es wird gut sein, zu zeichnen, memory grafische und mehr einfach:
Pfeile - zeigen Sie, wo Sie wachsen stack und heap, Prozess-stack-Größe zu begrenzen, definiert in OS, thread-stack-Größe, Grenzen, die durch die Parameter im thread erstellen-API in der Regel. Heap in der Regel die Begrenzung von Prozess-maximale Größe des virtuellen Speichers, für 32 bit 2-4 GB zum Beispiel.
So einfach Weg: Prozess-heap ist allgemein für Prozess-und alle Fäden im Innern, die Verwendung für die Speicherzuordnung im Allgemeinen Fall mit so etwas wie malloc().
Stack ist schnell der Speicher für store in common case-Funktion return Zeiger und Variablen verarbeitet, die als Parameter in den Funktionsaufruf, lokalen Funktions-Variablen.
InformationsquelleAutor Maxim Akristiniy
Da einige Antworten ging Erbsenzählerei, ich werde meinen Obolus beitragen.
Überraschend, niemand hat erwähnt, dass mehrere (D. H. nicht bezogen auf die Anzahl der OS-level-threads) - Aufruf-stacks sind nicht nur in exotischen Sprachen (PostScript) oder Plattformen (Intel Itanium), aber auch in Fasern, green threads und einige Implementierungen von Coroutinen.
Fasern, grünen Fäden und Coroutinen sind in vielerlei Hinsicht ähnlich, das führt zu viel Verwirrung. Der Unterschied zwischen Fasern und green threads ist, dass die frühere Nutzung kooperatives multitasking, während die letzteren können entweder kooperatives oder präemptives einen (oder sogar beide). Für die Unterscheidung zwischen Fasern und Coroutinen, siehe hier.
In jedem Fall der Zweck der beiden Fasern, grünen Fäden und Coroutinen ist, die mehrere Funktionen parallel ausgeführt, aber nicht parallel (siehe diese Frage ALSO für die Unterscheidung) innerhalb einer einzigen OS-level-thread, übertragen der Steuerung hin und her von einem anderen in einer organisierten Art und Weise.
Bei der Verwendung von Fasern, grüne Fäden oder Coroutinen, Sie in der Regel haben einen separaten Stapel pro Funktion. (Technisch, nicht nur einen stack, sondern ein ganzer Kontext der Ausführung wird pro Funktion. Am wichtigsten ist, CPU-Register.) Für jeden thread gibt es so viele stacks es sind parallel laufende Funktionen, und der thread ist die Umschaltung zwischen der Ausführung jeder Funktion nach der Logik des Programms. Wenn eine Funktion läuft bis zu seinem Ende, seine Einheit zerstört wird. So, die Anzahl und die Lebensdauer der stacks sind dynamisch und sind nicht bestimmt durch die Anzahl der OS-level-threads!
Beachten Sie, dass ich sagte: "in der Regel haben einen separaten Stapel pro Funktion". Es sind beide stackful und stackless Implementierungen von couroutines. Am bemerkenswertesten stackful C++ - Implementierungen sind Boost.Coroutine und Microsoft PPL's
async/await
. (Allerdings C++'s fortsetzbare Funktionen (ein.k.ein. "async
undawait
"), die vorgeschlagen wurden, um C++17, sind Sie wahrscheinlich stackless Coroutinen.)Fasern Vorschlag an die C++ standard-Bibliothek ist in Vorbereitung. Auch gibt es einige Drittanbieter -Bibliotheken. Grüne Fäden sind sehr beliebt in Sprachen wie Python und Ruby.
InformationsquelleAutor shakurov
Ich habe etwas zu teilen, obwohl die wichtigsten Punkte sind bereits abgedeckt.
Stack
Heap
Interessante Anmerkung:
InformationsquelleAutor Pankaj Kumar Thapa
Viele Antworten richtig sind, als Konzepte, aber wir müssen beachten, dass ein Stapel benötigt, um die hardware (z.B. Mikroprozessor) zu ermöglichen, aufrufen von Unterprogrammen (CALL in Assembler..). (OOP Jungs nennen es Methoden)
Auf dem stack-Sie sparen Rückkehr-Adressen und call - → push /ret → pop erfolgt direkt in der hardware.
Können Sie den stack-Parameter übergeben.. auch wenn es langsamer ist als die Verwendung von Registern (würde ein Mikroprozessor, der guru sagen oder eine gute 1980er Jahre das BIOS-Buch...)
Stack-Nutzung ist schneller als:
Willst du damit sagen, dass
malloc
ist ein kernel-Aufruf?1) ja, sorry.. OOP... 2) malloc: ich Schreibe kurz, sorry ... malloc ist im user-space.. aber auslösen kann Sie andere Anrufe.... der Punkt ist, dass mit heap KANN sehr langsam sein...
InformationsquelleAutor ingconti
Wow! So viele Antworten und ich glaube nicht, dass einer von Ihnen hat es hinbekommen.
1) Wo und was sind Sie (physisch in einer realen computer-Speicher)?
Ist der stack-Speicher beginnt, als die höchste Speicheradresse zugewiesen zu Ihrem Programm Bild, und es dann sinkt der Wert von dort aus. Es ist reserviert für die aufgerufene Funktion Parameter, und für alle temporären Variablen, die in Funktionen.
Gibt es zwei Haufen: öffentliche und private.
Dem privaten heap beginnt auf einer 16-byte-Grenze (für 64-bit-Programme) oder einen 8-byte-Grenze (für 32-bit-Programme) nach dem letzten byte code in Ihr Programm, und steigt dann im Wert von dort aus. Es wird auch als Standard-heap.
Wenn der private heap wird zu groß, überlappt Sie den stack-Bereich, so wird der stack überlappung der Haufen, wenn er zu groß wird. Da der stack beginnt bei einer höheren Adresse und arbeitet seinen Weg nach unten, um den unteren-Adresse, mit der richtigen hacking-Sie bekommen kann, machen die Stapel so groß, dass es überrennen die private heap-Bereich und überlappen Sie die code-Bereich. Der trick ist dann zu überschneidungen genug von den code-Bereich, können Sie Haken in den code. Es ist ein wenig schwierig zu tun und riskieren Sie einen Absturz, aber es ist einfach und sehr effektiv.
Der öffentlichkeit heap befindet sich in einem eigenen Speicherbereich außerhalb des Programms image space. Es ist diese Erinnerung, wird abgeschöpft werden nun auf die Festplatte, wenn der Speicher Ressourcen knapp sind.
2.) inwiefern werden Sie kontrolliert durch das Betriebssystem oder die Sprache der Laufzeit?
Den stack gesteuert, der durch den Programmierer, der private heap verwaltet wird durch die Bs und die öffentlichkeit heap wird von niemandem kontrolliert, weil es ein OS service-Sie stellen Anforderungen und entweder gewährt oder verweigert.
2b) Was ist Ihr Anwendungsbereich?
Sind Sie alle global auf dem Programm, aber deren Inhalte können sich private, public oder global.
2c), Was bestimmt die Größe eines jeden von Ihnen?
Die Größe des stack und des privaten heap sind, hängt von der compiler-runtime-Optionen. Die öffentlichkeit heap initialisiert wird zur Laufzeit mit Hilfe der parameter size.
2d), Was macht man schneller?
Sind Sie nicht entworfen, um schnell, Sie sind entworfen, um nützlich zu sein. Wie der Programmierer nutzt Sie bestimmt, ob Sie "schnell" oder "langsam"
REF:
https://norasandler.com/2019/02/18/Write-a-Compiler-10.html
https://docs.microsoft.com/en-us/windows/desktop/api/heapapi/nf-heapapi-getprocessheap
https://docs.microsoft.com/en-us/windows/desktop/api/heapapi/nf-heapapi-heapcreate
InformationsquelleAutor ar18