104 votes

Pourquoi la taille de la mémoire de la pile est-elle si limitée ?

Lorsque vous allouez de la mémoire sur le tas, la seule limite est la RAM libre (ou la mémoire virtuelle). Cela fait des Go de mémoire.

Alors pourquoi la taille de la pile est-elle si limitée (environ 1 Mo) ? Quelle raison technique vous empêche de créer des objets très volumineux sur la pile ?

Mise à jour : Mon intention n'est peut-être pas claire, je ne veulent pas pour allouer des objets énormes sur la pile et je n'ont pas besoin une plus grande pile. Cette question n'est que pure curiosité !

52voto

user1202136 Points 5230

Mon intuition est la suivante. La pile n'est pas aussi facile à gérer que le tas. La pile doit être stockée dans des emplacements mémoire continus. Cela signifie que vous ne pouvez pas allouer la pile de manière aléatoire selon les besoins, mais que vous devez au moins réserver des adresses virtuelles à cet effet. Plus la taille de l'espace d'adresses virtuelles réservé est grande, moins vous pouvez créer de threads.

Par exemple, une application 32 bits dispose généralement d'un espace d'adressage virtuel de 2 Go. Cela signifie que si la taille de la pile est de 2 Mo (comme par défaut dans pthreads), vous pouvez créer un maximum de 1024 threads. Cela peut être faible pour des applications telles que les serveurs web. Augmenter la taille de la pile à, disons, 100MB (c'est-à-dire que vous réservez 100MB, mais n'allouez pas nécessairement 100MB à la pile immédiatement), limiterait le nombre de threads à environ 20, ce qui peut être limitatif même pour de simples applications GUI.

Une question intéressante est de savoir pourquoi nous avons toujours cette limite sur les plateformes 64 bits. Je ne connais pas la réponse, mais je suppose que les gens sont déjà habitués à certaines "meilleures pratiques" en matière de pile : faire attention à ne pas allouer d'énormes objets sur le tas et, si nécessaire, augmenter manuellement la taille de la pile. Par conséquent, personne n'a jugé utile d'ajouter le support des piles "énormes" sur les plateformes 64 bits.

40voto

Andreas Grapentin Points 1968

Un aspect que personne n'a encore mentionné :

Une taille de pile limitée est un mécanisme de détection et de confinement des erreurs.

En général, le rôle principal de la pile en C et C++ est de garder la trace de la pile d'appels et des variables locales. Si la pile se développe hors limites, il s'agit presque toujours d'une erreur dans la conception et/ou le comportement de l'application.

Si la pile était autorisée à croître arbitrairement, ces erreurs (comme la récursion infinie) seraient détectées très tard, seulement après que les ressources du système d'exploitation soient épuisées. On évite cela en fixant une limite arbitraire à la taille de la pile. La taille réelle n'est pas très importante, si ce n'est qu'elle doit être suffisamment petite pour éviter la dégradation du système.

21voto

Bo Persson Points 42821

C'est juste une taille par défaut. Si vous avez besoin de plus, vous pouvez obtenir plus - le plus souvent en demandant à l'éditeur de liens d'allouer de l'espace de pile supplémentaire.

L'inconvénient d'avoir de grandes piles est que si vous créez de nombreux fils, ils auront besoin d'une pile chacun. Si toutes les piles allouent des multi-MBs, mais ne les utilisent pas, l'espace sera gaspillé.

Vous devez trouver le bon équilibre pour votre programme.


Certaines personnes, comme @BJovke, pensent que la mémoire virtuelle est essentiellement gratuite. Il est vrai que vous n'avez pas besoin d'avoir de la mémoire physique pour sauvegarder toute la mémoire virtuelle. Vous devez au moins être capable de donner des adresses à la mémoire virtuelle.

Cependant, sur un PC 32 bits typique, la taille de la mémoire virtuelle est la même que celle de la mémoire physique, car nous ne disposons que de 32 bits pour toute adresse, virtuelle ou non.

Comme tous les threads d'un processus partagent le même espace d'adressage, ils doivent le diviser entre eux. Et après que le système d'exploitation ait pris sa part, il ne reste "que" 2 à 3 Go pour une application. Et cette taille est la limite pour les deux le physique et la mémoire virtuelle, car il n'y a tout simplement plus d'adresses.

8voto

Ruud van Gaal Points 59

Pensez à la pile dans l'ordre du proche au lointain. Les registres sont proches de l'unité centrale (rapide), la pile est un peu plus loin (mais toujours relativement proche) et le tas est éloigné (accès lent).

La pile vit sur le tas, bien sûr, mais comme elle est utilisée en permanence, elle ne quitte probablement jamais le(s) cache(s) du CPU, ce qui la rend plus rapide que l'accès moyen au tas. C'est une raison pour garder la pile de taille raisonnable ; pour la garder en cache autant que possible. L'allocation de gros objets de pile (voire le redimensionnement automatique de la pile en cas de débordement) va à l'encontre de ce principe.

Il s'agit donc d'un bon paradigme pour les performances, et pas seulement d'un reliquat de l'ancien temps.

7voto

Scott Chamberlain Points 32782

D'une part, la pile est continue, donc si vous allouez 12MB, vous devez retirer 12MB lorsque vous voulez aller en dessous de ce que vous avez créé. De plus, déplacer des objets devient beaucoup plus difficile. Voici un exemple concret qui peut rendre les choses plus faciles à comprendre :

Disons que vous empilez des boîtes dans une pièce. Qu'est-ce qui est le plus facile à gérer :

  • empiler des boîtes de n'importe quel poids les unes sur les autres, mais lorsque vous avez besoin de prendre quelque chose au fond, vous devez défaire toute votre pile. Si vous voulez prendre un article de la pile et le donner à quelqu'un d'autre, vous devez enlever toutes les boîtes et déplacer la boîte vers la pile de l'autre personne (empilement uniquement).
  • Vous mettez tous vos cartons (à l'exception des cartons vraiment petits) dans une zone spéciale où vous n'empilez pas les choses les unes sur les autres et vous écrivez où vous les avez mis sur un morceau de papier (un pointeur) et vous mettez le papier sur la pile. Si vous devez donner la boîte à quelqu'un d'autre, il vous suffit de lui remettre le morceau de papier de votre pile, ou de lui donner une photocopie du papier et de laisser l'original là où il était dans votre pile. (Pile + tas)

Ces deux exemples sont des généralisations grossières et certains points de l'analogie sont manifestement erronés, mais ils sont suffisamment proches pour vous aider à voir les avantages des deux cas.

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X