Warum ist die Speicherzuweisung auf dem heap VIEL langsamer als auf den stack?
Mir wurde gesagt, dies viele Male. Aber ich weiß nicht WARUM...Was extra Kosten beteiligt ist, bei der Zuteilung von Speicher aus dem heap? Ist es hardware bedingt? Ist das mit dem CPU-Zyklen? So viele Vermutungen, aber keine genauen Antworten...Könnte jemand geben Sie mir einige der Ausarbeitung?
Nur als "entspannen Sie sich", sagte der Heap-Datenstruktur ist komplizierter als der Stack. Und meiner Meinung nach, einige Speicher zugeordnet ist, um einen thread als seinen Stack, wenn es zu laufen beginnt, während der heap teilen sich alle threads innerhalb eines Prozesses. Dieses Paradigma erfordern einige zusätzlichen Mechanismus zur Verwaltung der einzelnen thread ' s, Nutzung der shared-heap, wie z.B. Garbage Collection. Bin ich richtig auf dieser?
- Siehe stackoverflow.com/questions/161053/..., es geht um C++, aber das Konzept ist das gleiche.
Du musst angemeldet sein, um einen Kommentar abzugeben.
Da der heap ist eine weit kompliziertere Datenstruktur als der stack.
Für viele Architekturen, die Zuteilung von Speicher auf dem stack ist nur eine Frage der änderung der stack-pointer, d.h. es ist eine Anweisung. Reservieren von Speicher auf dem heap beinhaltet, suchen für einen ausreichend großen block, Aufteilung und Verwaltung des "book-keeping", die erlaubt, dass Dinge wie
free()
in einer anderen Reihenfolge.Speicher auf dem Stapel reserviert ist garantiert zu werden freigegeben, wenn der Gültigkeitsbereich (typischerweise die Funktion) beendet, und es ist nicht möglich, deallocate nur einige davon.
Ihre Bearbeitung, wo Sie noch einmal entspannen, die Antwort, die Sie erwähnen, die "heap-Datenstruktur". Seien Sie sehr vorsichtig, da die Datenstruktur bekannt als heap hat keine Beziehung zu dynamic memory allocation. Ganz klar, ich verwende die Sprache mehr Anwalt Terminologie der free store.
Es wurde bereits darauf hingewiesen, stack Allokation erfordert das Inkrementieren eines Zeigers, die in der Regel eine dedizierte register auf den meisten Architekturen und-Freigabe erfordert die gleiche Menge an Arbeit. Stack Zuweisungen sind auch eingeschränkt auf eine bestimmte Funktion. Dies macht Sie viel bessere Kandidaten für compiler-Optimierungen wie precomputing der insgesamt benötigten Speicherplatz auf dem stack und dabei ein einziges Inkrement für einen ganzen stack frame. Ebenso wurde der Stapel besser gewährleistet Daten-Lokalität. Der stack-Spitze ist fast immer garantiert innerhalb einer cache-line, und wie ich bereits erwähnt, der stack-pointer ist in der Regel gespeichert in einem register. Die Optimierung der Compiler auf manchen Architekturen kann sogar zu eliminieren Zuweisungen insgesamt sind auf dem stack durch die Wiederverwendung von Argumenten aus den vorherigen stack-frames übergeben werden als Argumente an Funktionen aufgerufen, die in tiefer stack-frames. Ebenso stack zugewiesenen Variablen können oft gefördert werden, um registriert zu vermeiden Zuweisungen als gut.
Im Gegensatz, der freie Speicher ist viel komplexer. Ich bin es gar nicht erst zu beginnen, zu decken, garbage collection-Systeme, weil das ist ein ganz anderes Thema, und diese Frage wurde gebeten, über die C-Sprache. In der Regel Zuweisungen und deallocations von einem free-Shop umfassen mehrere verschiedene Daten-Strukturen, wie eine freie Liste oder block-pool. Diese Datenstrukturen und Buchhaltung erfordern Speicher, und damit, dass Raum verschenkt wird. Darüber hinaus wird die Buchführung Aufzeichnungen sind oft vermischt mit den Zuweisungen und schade damit der Daten-Lokalität von anderen Zuweisungen. Die Zuweisungen aus dem freien Speicher kann bedeuten, zu Fragen, das zugrunde liegende Betriebssystem für mehr Prozess-Speicher in der Regel aus irgendeiner form der slab allocator.
Für einen einfachen Vergleich und mit jemalloc-2.2.5 und zahlen von sloccount als Referenz, die jemalloc Umsetzung enthält mehr als 8.800 Zeilen Quellcode in der Sprache C und die anderen über 700 Zeilen Testcode. Dies sollte Ihnen eine gute Idee, den Unterschied in der Komplexität zwischen freier Speicher-Allokation und-stack-Vergabe: Tausende Zeilen C-code im Vergleich zu einem einzelnen Unterricht.
Zusätzlich, da freie Speicher Zuweisungen sind nicht beschränkt auf einen einzelnen lexikalischen Umfang, die Lebensdauer des jede Zuordnung muss verfolgt werden. Ebenso werden diese Zuordnungen können übergeben werden mehrere threads, und somit thread-Synchronisation-Probleme geben, das problem Raum. Ein weiteres großes problem für die Kostenlose store-Zuordnung ist die Fragmentierung. Fragmentierung verursacht viele Probleme:
Auf modernen Systemen, stacks sind oft relativ klein im Vergleich zu den freien Speicher, also letztlich auch das freie speichern ist die Verwaltung mehr Platz und somit der Bekämpfung schwerer problem. Auch aufgrund der Einschränkungen der stack-Größe, der freie Speicher wird in der Regel für größere Zuweisungen, die diese Diskrepanz zwischen der Behandlung von sehr großen und sehr kleinen Zuordnungen macht die Aufgabe der free store härter als gut. In der Regel stack Zuweisungen sind klein, in der Größenordnung von ein paar Kilobyte oder weniger, und die Gesamt Größe des Stapels ist nur ein paar Megabyte. Der freie Speicher ist in der Regel gegeben die gesamten restlichen Prozess Raum in einem Programm. Auf modernen Maschinen können mehrere hundert Gigabyte, und es ist nicht ungewöhnlich für freien Speicher Zuweisungen variieren in der Größe von wenigen bytes, wie eine kurze Zeichenfolge von Zeichen in Megabyte oder sogar Gigabyte an beliebigen Daten. Dies bedeutet, dass der freie Speicher allocators zu tun haben mit dem zugrunde liegenden Betriebssystem virtuellen Speicher-management. Stack-Allokation ist grundsätzlich das in der computer-hardware.
Wenn Sie wollen wirklich lernen, über die Kostenlose store-Aufteilung, ich würde empfehlen, das Lesen einige der vielen Beiträge und Artikel veröffentlicht über verschiedene malloc-Implementierungen oder auch das Lesen des Codes. Hier ein paar links zum Einstieg:
Hier ein paar zusätzliche links mit Beschreibungen der tcmalloc-Implementierung:
Der wesentliche Unterschied zwischen einem stack und ein heap ist, dass die Elemente auf einem stack kann nicht entfernt werden, aus, um. Wenn Sie hinzufügen von Elementen A, B, C zu einem Stapel, können Sie nicht entfernen B ohne entfernen der C ersten. Dies bedeutet, dass das hinzufügen eines neuen Elements zu einem stack immer bedeutet, indem es der Ende von dem Stapel, das ist eine sehr einfache Bedienung. Sie bewegen den Zeiger, die Punkte an das Ende des Stapels.
Auf einem Haufen auf der anderen Seite, Sie kann entfernen von Elementen aus der Bestellung. Und solange Sie sich nicht bewegen, die anderen Gegenstände, um danach im Speicher (wie einige Müll-heaps tun), Ihr heap hat dann ein "Loch" in der Mitte. I. e. wenn Sie add A,B,C auf einen Haufen, und entfernen Sie B-heap sieht im Speicher: A _ C wobei " _ " ist ein block von ungenutzten (freien) Speicher. Wenn Sie ein neues Element hinzufügen D nun, die Zuweisung zu finden, ununterbrochenen freien Speicher groß genug, um D. Je nachdem, wie viele kontinuierliche Freiräume gibt es in Ihrem Speicher, dies kann eine teure operation sein. Und es ist fast immer teurer als eine Bewegung der "letzten element" Zeiger auf einem Stapel.