2009-07-31 8 views
2

Doublons possibles:
How is heap and stack memories mananged, implemented, allocated?
Stack,Static and Heap in C++Comment est tas et la pile des souvenirs mananged, mis en œuvre, attribué

en C/C++, nous pouvons stocker des variables, des fonctions, des fonctions membres, les instances d'un classe soit sur une pile ou un tas.

Comment est-ce que chacun est implémenté? Comment est-il géré (niveau élevé)? Gcc préaffecte-t-il un morceau de mémoire à utiliser pour la pile et le tas, puis distribue-t-il sur demande? La mémoire d'origine provient-elle de la RAM?

Une fonction peut-elle être allouée sur le tas au lieu d'une pile? Je m'interroge vraiment sur la mise en œuvre et la gestion des mémoires tas et pile. After reading referenced question, Je n'ai pas trouvé quelque chose qui adresse cela ... merci pour le lien

+3

double exact de question fermée: http://stackoverflow.com/questions/1212797/how-is-heap-and-stack-memories-mananged-implemented-allocated-closed – Pete

+2

Merci de ne pas republier quand les gens fermeront votre question en double (et j'ai voté pour rouvrir votre autre question, mais je vais voter pour fermer celle-ci en double). – Zifre

+0

@pete regardez les commentaires de la copie exacte. thx –

Répondre

10

Je pense à votre question, on peut facilement écrire au moins quelques chapitres pour le livre sur les systèmes d'exploitation. Je vous suggère de lire Tanenbaum: Modern Operating Systems.

Différence principale de tas et pile, que l'un est par élément de processus, l'autre par élément de thread. Initialement, lorsque le programme est démarré, il obtient un tas minimum et un segment de pile. Le tas est développé, la pile est statique (pour chaque thread). Si vous écrivez une fonction récursive qui ne se termine pas (récursivité infinie), vous aurez un débordement de pile;) Tout appel de fonction a un cadre de pile sur le segment de pile, lorsque la fonction quitte, la pile est déroulée et le cadre est libre pour être utilisé par le prochaine fonction. La pile est une structure linéaire continue. Sous Linux, vous pouvez configurer la taille du segment de pile pour un processus via une variable d'environnement. Sous Windows (au moins avec MS Visual C++), vous pouvez passer un indicateur de lien avec la taille du segment de pile. Stack trop-pleins peuvent également être produits lors de l'attribution au moment de la compilation un peu grand tableau:

char test[1000000]; 

Heap est une autre histoire. Quand un processus démarre, la taille du tas est une valeur par défaut et peut varier du système d'exploitation au système d'exploitation ou à la configuration utilisée sur ce système (par exemple, sur Windows, elle est 2 Mo par défaut). De plus, si vous avez besoin de plus de tas, pour allouer plus d'espace pour les variables, etc. Si le programme ne libère pas la mémoire de tas, il n'y en a plus (ou espace de tas). Il existe différentes structures de données pour l'implémentation de tas. Certaines d'entre elles sont des dérivées d'arbres binaires, d'autres ne le sont pas. Fibonacci Heap (forêt d'arbres). Vous pouvez lire quelques articles etc. sur comment écrire un allocateur de mémoire. Ces structures de données doivent être optimisées pour trouver le noeud tas quand un bloc alloué doit être désaffecté, ou en ajoutant (trouver un morceau libre) lorsqu'un nouvel espace tas est nécessaire.

Chaque processus sur un système d'exploitation 32 bits dispose de 4 Go d'espace d'adressage virtuel. Comme vous pouvez l'imaginer, il ne peut y avoir autant de RAM où tous les processus avec leurs 4 Go d'espace d'adressage virtuel correspondent. La mémoire du système d'exploitation est organisée en pages, qui sont permutées sur HD lorsqu'elles ne sont plus nécessaires ou expirées. C'est là que la pagination vient jouer. Tout est mappé aux pages: un processus avec la pile ou le tas croissant. En raison de la structure de tas qu'il développe dynamiquement, il peut être placé sur plusieurs pages. C'est pourquoi l'accès au tas peut être très coûteux, car si la page n'est pas en mémoire, une erreur de page se produit et le système d'exploitation doit charger une page du disque (et cela peut être plus lent). Le cadre de pile du thread en cours d'exécution est dans le cache du processeur, ce qui est beaucoup plus rapide que la RAM.

Différents types de tas sont possibles, il peut y avoir des tas qui sont très rapides pour les petits objets ou des tas qui sont très efficaces dans les environnements multithread. Alexandrescu décrit dans "Modern C++ Design" comment développer un petit allocateur d'objet et un tas qui gère de petits objets. Cette implémentation est disponible dans sa bibliothèque Loki C++. Certains systèmes embarqués offrent des régions de mémoire physiquement différentes, où différents types de tas peuvent être mis en œuvre sur ontop. Écrire un propre allocateur (gestionnaire de tas, etc.) est un travail difficile si vous voulez battre un compilateur.

Cordialement,
Ovanes

+0

Ce serait bien si cela pouvait être déplacé à l'autre question d'ultraman, pratiquement identique, http://stackoverflow.com/questions/1212797/how-is-heap-and-stack-memories-mananged-implemented-allocated ... – SamB

Questions connexes