[gull] nombre instance max avec find

Marc SCHAEFER schaefer at alphanet.ch
Wed Aug 24 09:19:27 CEST 2005


On Tue, Aug 23, 2005 at 06:33:33PM +0200, Daniel Cordey wrote:
> Pour benefichier au maximum de l'effet 'N', il faut que le programme soit tres 
> petit (au niveau code) et qu'il utilise exclusivement des 'shared libraries'. 
> Sinon, chaque libraririe (ou portion de code) statique sera dupliquee dans la 
> memoire !!! Toutefois, il faut encore que le programme soit fortement oriente 

La section `text' (le code non modifiable) d'une application est en
général, sous UNIX, partagé entre les différentes instances de cette
application, comme le sont d'ailleurs les bibliothèques partagées
(enfin, la partie `text' de celles-ci, voir plus bas).

D'ailleurs, quand il n'y a pas assez de mémoire physique dans le
système, tout ce qui est `text' peut être rendu (désalloué) directement.
Lorsque cette section de code sera réaccédée, elle sera rechargée de
l'exécutable. En fait, pour être précis, UNIX ne charge jamais
d'exécutable. Il mmap(2) simplement le fichier de l'exécutable
dans l'espace mémoire (address space) du processus, et c'est l'accès
à la zone mémoire concernée qui, via le MMU, provoque une faute
de page, appelle le handler de cette page, puis transfère la page
concernée du disque.  C'est du chargement à la demande ou du lazy loading.

Si un exécutable ou un .so est mappé (read-only) dans plusieurs
processus, la mémoire physique ne sera allouée qu'une fois, au premier
accès.

Un type de mapping intéressant est le copy-on-write: en bref, une zone
cette fois modifiable est partagée entre plusieurs processus. Lorsqu'un
des processus modifie une page, la page est dupliquée et le mapping
modifié (et donc une allocation éventuellement d'une autre page physique
est provoquée). Notons que certains .so (shared object, en bref une
bibliothèque partagée) contiennent aussi des sections modifiables.

Inutile de dire que ces comportements rendent tout déterministe dans
l'allocation réelle de mémoire très difficile, sauf si l'on prend
toujours le pire cas en compte (d'où gaspillage).

Seules les sections de BSS (données à initialiser) et de données
allouées (pile et tas) sont candidates pour le swapping -- en fait le
paging, page par page (usuellement 4k sur ix86) sur la zone de swap.

L'erreur `text file busy' est parfois rencontrée si l'on essaie de
remplacer le contenu d'un exécutable alors que celui-ci est utilisé. Un
`mv programme programme.OLD && cp /tmp/bla programme' est recommandé.

Enfin, certains kernels UNIX (pas Linux) supportent le préchargement ou
le chargement unique de zones de `text' en mettant le sticky bit (+t)
sur l'exécutable. Sous Linux cela active plutôt le `mandatory locking'
-- qui n'est pas activé par défaut dans le kernel.

Pourquoi le code non modifiable s'appelle `text' sous UNIX doit remonter
à il y a bien longtemps.

   schaefer at voyager:/data/home/schaefer$ file /bin/ls
   /bin/ls: ELF 32-bit LSB executable, Intel 80386, version 1 (SYSV), for GNU/Linux

   schaefer at voyager:/data/home/schaefer$ objdump -x /bin/ls > /tmp/a
extraits:
   Sections:
   Idx Name          Size      VMA       LMA       File off  Algn
    11 .text         0000be90  08049a10  08049a10  00001a10  2**4
                     CONTENTS, ALLOC, LOAD, READONLY, CODE

voir aussi /proc/PID/maps

Là où il faut effectivement faire attention, c'est que la compilation
statique de programmes *différents* gaspille effectivement de la
mémoire lorsqu'ils sont chargés ensemble.




More information about the gull mailing list