Question

  

Doublons possibles:
   Comment les mémoires de tas et de pile sont-elles gérées, implémentées, allouées?
   Pile, statique et tas en C ++

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

Comment chacun est-il implémenté? Comment est-il géré (haut niveau)? Est-ce que gcc préalloue un bloc de mémoire à utiliser pour la pile et le tas, puis est distribué 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?

             --Clarification--

Je parle vraiment de la mise en œuvre et de la gestion des mémoires de tas et de piles. Après avoir lu la question référencée, je n'ai rien trouvé qui réponde à cette .. merci pour le lien

Était-ce utile?

La solution

Je pense qu’à 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: systèmes d’exploitation modernes.

Différence principale entre le tas et la pile, celle-ci étant par élément de processus, l'autre par élément de fil. Initialement, lorsque le programme est lancé, il obtient un segment de pile minimal 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écursion sans fin), vous obtiendrez un débordement de pile;) Tout appel de fonction comporte un cadre de pile sur un segment de pile. fonction suivante. 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 transmettre un indicateur de l'éditeur de liens avec la taille du segment de pile. Des dépassements de capacité peuvent également être générés lors de l’allocation, lors de la compilation, d’un grand tableau:

char test[1000000];

Heap est une histoire différente. Lorsqu'un processus démarre, la taille du tas correspond à une valeur par défaut et peut varier d'un système à l'autre ou à la configuration utilisée sur ce système (par exemple, sous Windows, elle correspond à 2 Mo par défaut, pour autant que je m'en souvienne). En outre, si vous avez besoin de plus de tas, allouez plus d’espace aux variables, etc., cela augmentera. Si le programme ne libère pas de la mémoire de tas, il en manque (ou de l'espace de tas). Il existe différentes structures de données pour la mise en œuvre de tas, certaines d'entre elles sont des dérivés d'arborescence binaire, d'autres pas. Fibonacci Heap (forêt d'arbres). Vous pouvez lire des articles, etc., sur la façon d'écrire un allocateur de mémoire. Ces structures de données doivent être optimisées pour rechercher le nœud de segment de mémoire lorsqu'un bloc alloué doit être désalloué ou pour ajouter (recherche d'un bloc libre) lorsqu'un nouvel espace de segment de mémoire 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 pas y avoir autant de RAM où s'adapte tous les processus avec leurs 4 Go d'espace d'adressage virtuel. La mémoire du système d'exploitation est organisée en pages qui sont permutées en HD lorsqu'elles ne sont plus nécessaires ou expirées. C'est ici que la pagination vient jouer. Tout est mappé sur des pages: un processus avec la pile ou le tas en croissance. En raison de la structure dynamique du segment de mémoire, 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 à partir du disque (et cela peut être plus lent en raison de la magnitude). Le cadre de pile du thread en cours d'exécution se trouve 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 très rapides pour les petits objets ou des tas très efficaces dans les environnements multithreads. Alexandrescu décrit dans "Modern C ++ Design". comment développer un allocateur de petits objets et un tas qui gère les petits objets. Cette implémentation est disponible dans sa bibliothèque Loki C ++. Certains systèmes intégrés offrent des régions de mémoire physiquement différentes, dans lesquelles différents types de segments de mémoire peuvent être implémentés au sommet. Écrire un propre allocateur (gestionnaire de tas, etc.) est un travail difficile si vous voulez battre un compilateur.

Cordialement,
Ovanes

Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top