Il y a naturellement beaucoup de questions liées sur l'allocation de pile
Quoi et où sont la pile et le tas?
Pourquoi la taille de la pile est-elle limitée?
Taille de la pile et de la mémoire vive
Cependant, sur diverses machines * nix, je peux lancer la commande bash
ulimit -s unlimited
ou la commande csh
set stacksize unlimited
Comment cela change-t-il la manière dont les programmes sont exécutés? Existe-t-il des impacts sur les performances du programme ou du système (par exemple, pourquoi ne serait-ce pas le cas par défaut)?
Si plus de détails sur le système sont pertinents, je suis principalement concerné par les programmes compilés avec GCC sous Linux fonctionnant sur du matériel x86_64.
Lorsque vous appelez une fonction, un nouvel "espace de noms" est alloué sur la pile. C'est ainsi que les fonctions peuvent avoir des variables locales. Lorsque les fonctions appellent des fonctions, qui à leur tour appellent des fonctions, nous continuons à allouer de plus en plus d’espace sur la pile pour conserver cette hiérarchie profonde des espaces de noms.
Pour limiter les programmes utilisant d’énormes quantités d’espace de pile, une limite est généralement définie via ulimit -s
. Si nous supprimons cette limite via ulimit -s unlimited
, nos programmes pourront continuer à engloutir RAM pour leur pile toujours croissante, jusqu’à épuisement total de la mémoire système.
int eat_stack_space(void) { return eat_stack_space(); }
// If we compile this with no optimization and run it, our computer could crash.
Habituellement, utiliser une tonne d’espace de pile est accidentel ou est le symptôme d’une récursion très profonde qui ne devrait probablement pas s’appuyer beaucoup sur la pile. Donc la limite de pile.
L'impact sur la performance est mineur mais existe. En utilisant la commande time
, j'ai constaté que l'élimination de la limite de pile augmentait les performances de quelques fractions de seconde (au moins sous Ubuntu 64 bits).
Mea culpa, taille de la pile peut en effet être illimité. _STK_LIM
est le par défaut , _STK_LIM_MAX
est quelque chose qui diffère selon l'architecture, comme on peut le voir dans include/asm-generic/resource.h
:
/*
* RLIMIT_STACK default maximum - some architectures override it:
*/
#ifndef _STK_LIM_MAX
# define _STK_LIM_MAX RLIM_INFINITY
#endif
Comme on peut le voir dans cet exemple, la valeur générique est infinie, où RLIM_INFINITY
est à nouveau dans le cas générique défini comme suit:
/*
* SuS says limits have to be unsigned.
* Which makes a ton more sense anyway.
*
* Some architectures override this (for compatibility reasons):
*/
#ifndef RLIM_INFINITY
# define RLIM_INFINITY (~0UL)
#endif
Donc, je suppose que la vraie réponse est que - la taille de la pile PEUT être limitée par une architecture, alors une trace de pile illimitée signifiera tout ce que _STK_LIM_MAX
est défini sur, et dans le cas contraire, il est infini. Pour plus de détails sur ce que signifie le régler à l'infini et sur les implications possibles, reportez-vous à l'autre réponse, c'est bien meilleur que le mien.
"ulimit -s unlimited" permet à la pile de croître sans limite. Cela peut empêcher votre programme de planter si vous écrivez des programmes par récursion, en particulier si vos programmes ne sont pas récursifs (les compilateurs peuvent "optimiser" ceux-ci), et que la profondeur de la récursivité est grande.
La réponse de @seisvelas contient presque la bonne réponse à la question. Cependant, il est profondément enfoui dans une multitude de fausses déclarations - voir les commentaires. Ainsi, je me suis senti obligé d'écrire cette réponse.