En bref
Une pile est utilisée pour l'allocation de mémoire statique et un tas pour l'allocation de mémoire dynamique, tous deux stockés dans la RAM de l'ordinateur.
En détail
La pile
La pile est une structure de données "LIFO" (dernier entré, premier sorti), qui est gérée et optimisée par le CPU de manière assez étroite. Chaque fois qu'une fonction déclare une nouvelle variable, elle est "poussée" sur la pile. Ensuite, chaque fois qu'une fonction se termine, toutes les variables poussées sur la pile par cette fonction sont libérées (c'est-à-dire qu'elles sont supprimées). Une fois qu'une variable de pile est libérée, cette région de mémoire devient disponible pour d'autres variables de pile.
L'avantage d'utiliser la pile pour stocker des variables est que la mémoire est gérée pour vous. Vous n'avez pas à allouer de la mémoire à la main, ni à la libérer une fois que vous n'en avez plus besoin. De plus, parce que le CPU organise la mémoire de pile de manière si efficace, la lecture et l'écriture dans les variables de pile sont très rapides.
Plus d'informations peuvent être trouvées ici .
Le tas
Le tas est une région de la mémoire de votre ordinateur qui n'est pas gérée automatiquement pour vous et n'est pas aussi étroitement gérée par le CPU. Il s'agit d'une région de mémoire plus flottante (et plus grande). Pour allouer de la mémoire sur le tas, vous devez utiliser malloc () ou calloc (), qui sont des fonctions C intégrées. Une fois que vous avez alloué de la mémoire sur le tas, vous êtes responsable de l'utilisation de free () pour désallouer cette mémoire une fois que vous n'en avez plus besoin.
Si vous ne le faites pas, votre programme aura ce que l'on appelle une fuite de mémoire. Autrement dit, la mémoire sur le tas sera toujours mise de côté (et ne sera pas disponible pour d'autres processus). Comme nous le verrons dans la section de débogage, il existe un outil appelé Valgrind qui peut vous aider à détecter les fuites de mémoire.
Contrairement à la pile, le tas n'a pas de restrictions de taille sur la taille variable (à part les limitations physiques évidentes de votre ordinateur). La mémoire du tas est légèrement plus lente à lire et à écrire, car il faut utiliser des pointeurs pour accéder à la mémoire sur le tas. Nous parlerons des pointeurs sous peu.
Contrairement à la pile, les variables créées sur le tas sont accessibles par n'importe quelle fonction, n'importe où dans votre programme. Les variables de tas ont une portée essentiellement globale.
Plus d'informations peuvent être trouvées ici .
Les variables allouées sur la pile sont stockées directement dans la mémoire et l'accès à cette mémoire est très rapide, et son allocation est traitée lors de la compilation du programme. Lorsqu'une fonction ou une méthode appelle une autre fonction qui à son tour appelle une autre fonction, etc., l'exécution de toutes ces fonctions reste suspendue jusqu'à ce que la toute dernière fonction renvoie sa valeur. La pile est toujours réservée dans un ordre LIFO, le dernier bloc réservé est toujours le prochain bloc à libérer. Cela rend vraiment simple de garder une trace de la pile, libérer un bloc de la pile n'est rien de plus que d'ajuster un pointeur.
Les variables allouées sur le tas ont leur mémoire allouée au moment de l'exécution et l'accès à cette mémoire est un peu plus lent, mais la taille du tas n'est limitée que par la taille de la mémoire virtuelle. Les éléments du tas n'ont aucune dépendance les uns avec les autres et peuvent toujours être consultés au hasard à tout moment. Vous pouvez allouer un bloc à tout moment et le libérer à tout moment. Cela rend beaucoup plus complexe le suivi des parties du tas allouées ou libres à un moment donné.
Vous pouvez utiliser la pile si vous savez exactement combien de données vous devez allouer avant la compilation et qu'elle n'est pas trop volumineuse. Vous pouvez utiliser le tas si vous ne savez pas exactement combien de données vous aurez besoin lors de l'exécution ou si vous avez besoin d'allouer beaucoup de données.
Dans une situation multithread, chaque thread aura sa propre pile complètement indépendante, mais ils partageront le tas. La pile est spécifique au thread et le tas est spécifique à l'application. La pile est importante à considérer dans la gestion des exceptions et les exécutions de threads.
Chaque thread obtient une pile, alors qu'il n'y a généralement qu'un seul segment pour l'application (bien qu'il ne soit pas rare d'avoir plusieurs segments pour différents types d'allocation).
Au moment de l'exécution, si l'application a besoin de plus de segment, elle peut allouer de la mémoire à partir de la mémoire libre et si la pile a besoin de mémoire, elle peut allouer de la mémoire à partir de la mémoire allouée à la mémoire libre pour l'application.
Même, plus de détails sont donnés ici et ici .
Venons-en maintenant aux réponses à votre question .
Dans quelle mesure sont-ils contrôlés par le système d'exploitation ou le langage d'exécution?
Le système d'exploitation alloue la pile pour chaque thread au niveau du système lorsque le thread est créé. En règle générale, le système d'exploitation est appelé par le langage d'exécution pour allouer le segment de mémoire à l'application.
Plus d'informations peuvent être trouvées ici .
Quelle est leur portée?
Déjà donné en haut.
"Vous pouvez utiliser la pile si vous savez exactement combien de données vous devez allouer avant la compilation et qu'elle n'est pas trop grande. Vous pouvez utiliser le tas si vous ne savez pas exactement combien de données vous aurez besoin au moment de l'exécution ou si vous devez allouer beaucoup de données. "
Plus d'informations peuvent être trouvées ici .
Qu'est-ce qui détermine la taille de chacun d'eux?
La taille de la pile est définie par le système d' exploitation lors de la création d'un thread. La taille du segment de mémoire est définie au démarrage de l'application, mais elle peut augmenter à mesure que l'espace est nécessaire (l'allocateur demande plus de mémoire au système d'exploitation).
Qu'est-ce qui rend un plus rapide?
L'allocation de pile est beaucoup plus rapide car elle ne fait que déplacer le pointeur de pile. En utilisant des pools de mémoire, vous pouvez obtenir des performances comparables grâce à l'allocation de tas, mais cela s'accompagne d'une légère complexité supplémentaire et de ses propres maux de tête.
En outre, la pile par rapport au tas n'est pas seulement une considération de performance; il vous en dit également beaucoup sur la durée de vie attendue des objets.
Les détails peuvent être trouvés ici .