Stack tailles
Typiquement, chaque fil a une pile fixe lorsque le fil est créé. Exécutez ulimit -a
pour voir la taille de la pile par défaut pour votre système. Sur mon système, c'est 8 MiB. Lorsque vous créez de nouveaux threads, vous pouvez leur attribuer des piles plus petites ou plus grandes (voir pthread_attr_setstacksize
). Lorsque la pile croît au-delà de 8 Mio, le programme écrira dans un emplacement mémoire invalide et tombera en panne. Le noyau s'assure que les emplacements de mémoire à côté de la pile sont tous invalides, pour s'assurer que les programmes se bloquent lorsque leurs piles débordent.
Vous pouvez penser qu'une taille fixe est une perte, mais 8 MiB est la mémoire virtuelle et non mémoire physique. La différence est importante, voir ci-dessous.
Malloc
Sur les systèmes Unix, l'allocation de mémoire a deux couches à elle. La couche d'espace utilisateur est malloc
(et calloc
, realloc
, free
).Cela fait partie de la bibliothèque C, et peut être remplacé par votre propre code - Firefox le fait, et de nombreux langages de programmation utilisent leur propre schéma d'allocation autre que malloc
. Diverses implémentations malloc
sont multi-plateforme. La couche inférieure est mmap
et sbrk
. La fonction mmap
est un appel système qui modifie l'espace d'adressage de votre programme. Une des choses qu'il peut faire est d'ajouter de nouvelles pages privées et anonymes dans la mémoire de votre programme.
Le but de malloc
est d'obtenir de gros morceaux de mémoire virtuelle du noyau en utilisant mmap
(ou sbrk
) et de les répartir efficacement pour votre programme. L'appel système mmap
ne fonctionne que par multiples de 4 KiB (sur la plupart des systèmes).
Mémoire: virtuel par rapport réel
Rappelez-vous que la pile et l'ensemble de la mémoire retournée par mmap
est juste la mémoire virtuelle, pas RAM physique. Le noyau n'alloue pas de RAM physique à votre processus tant que vous ne l'utilisez pas réellement.
Lorsque vous obtenez une mémoire anonyme du noyau, soit sur le tas ou la pile, elle est remplie de zéros. Au lieu de vous donner des centaines de pages de RAM physique pré-remplie avec des zéros, cependant, le noyau fait que toute cette mémoire virtuelle partage une seule page de RAM physique. La mémoire virtuelle est marquée en lecture seule. Dès que vous y écrivez, le processeur lève une exception, transfère le contrôle au noyau et le noyau alloue une nouvelle page, inscriptible, mise à zéro pour votre programme.
Ceci explique pourquoi:
calloc
est plus rapide que malloc
+ memset
(car calloc
sait que les mmap
« pages d sont pré-mise à zéro et memset
force l'allocation de mémoire vive)
- Vous pouvez allouer beaucoup plus de mémoire que combiné RAM + swap (car il n'est pas utilisé jusqu'à ce que vous écrivez à lui)
Merci beaucoup pour la réponse. Aussi, je lis un livre d'OS, il dit que malloc alloue de l'espace sur l'espace de swap, donc j'ai posé la question d'une manière différente. – mousey
"malloc" ne mappe pas la mémoire physique dans votre processus, à la place, le noyau le fait une fois que vous écrivez dans la mémoire retournée par malloc. Vous pouvez expérimenter pour vous-même: même si vous malloc centaines de megs, la quantité de RAM physique utilisée n'augmentera pas. –
@Dietrich Donc, il devrait être mappé à mon adresse virtuelle non? Un autre programme sage ne fonctionne pas! – mousey