Quand les commandes intégrées sont-elles chargées en mémoire

11

Disons que si je tape cddans ma coquille. Est cdchargé de la mémoire à ce moment? Mon intuition est que ces commandes intégrées sont préchargées dans la mémoire système après le chargement du noyau, mais quelqu'un a insisté sur le fait qu'elles ne sont chargées que lorsque j'invoque réellement la commande (appuyez sur Entrée sur un shell). Pourriez-vous s'il vous plaît me dire s'il existe une référence qui explique cela?

Prévoyant
la source
1
Je pense que cette réponse vous aiderait à comprendre, même si ce n'est pas tout à fait un doublon.
cjm
@cjm: Merci, c'était en effet une bonne explication à lire.
Prédicateur

Réponses:

9

Disons que si je tape cd dans mon shell. Le CD est-il chargé à partir de la mémoire à ce moment? Mon intuition est que ces commandes intégrées sont préchargées dans la mémoire système après le chargement du noyau, mais quelqu'un a insisté pour qu'elles ne soient chargées que lorsque j'invoque réellement la commande ...

En termes généraux, les autres réponses sont correctes - les commandes intégrées sont chargées avec le shell, les commandes autonomes sont chargées lorsqu'elles sont appelées. Cependant, un «quelqu'un» de belette très collant pourrait insister sur le fait que ce n'est pas si simple.

Cette discussion porte un peu sur le fonctionnement du système d'exploitation et sur les différents systèmes d'exploitation, mais je pense qu'en général, ce qui suit est probablement vrai pour tous les * nix contemporains.

Premièrement, «chargé en mémoire» est une phrase ambiguë; ce à quoi nous faisons référence, c'est que son espace d'adressage virtuel est mappé en mémoire . Ceci est important parce que «l'espace d'adressage virtuel» fait référence à des éléments qui peuvent devoir être placés en mémoire, mais qui ne le sont en fait pas au départ: ce qui est réellement chargé en mémoire est principalement la carte elle - même - et la carte n'est pas le territoire. Le «territoire» serait l'exécutable sur disque (ou dans le cache disque) et, en fait, la plupart de ces éléments ne sont probablement pas chargés en mémoire lorsque vous appelez un exécutable.

En outre, une grande partie du «territoire» est constituée de références à d'autres territoires (bibliothèques partagées), et encore une fois, le simple fait qu'ils soient mentionnés ne signifie pas non plus qu'ils sont vraiment chargés. Ils ne sont pas chargés tant qu'ils ne sont pas réellement utilisés, et alors seuls les morceaux d'entre eux qui doivent réellement être chargés pour que «l'utilisation» réussisse.

Par exemple, voici un extrait de topsortie sur linux faisant référence à une bashinstance:

VIRT  RES  SHR S %CPU %MEM    TIME+  COMMAND                                  
113m 3672 1796 S  0.0  0.1   0:00.07 bash   

Le VIRT de 113 Mo est l'espace d'adressage virtuel, qui est mappé en RAM. Mais RES est la quantité réelle de RAM consommée par le processus - seulement 3,7 ko. Et de cela, certains font partie du territoire partagé mentionné ci-dessus - 1,8 kB SHR. Mais mon /bin/bashdisque est de 930 Ko, et la bibliothèque de base à laquelle il est lié (une bibliothèque partagée) est encore deux fois plus grande.

Cet obus ne fait rien pour le moment. Disons que j'invoque une commande intégrée, qui, nous l'avons dit plus tôt, était déjà "chargée en mémoire" avec le reste du shell. Le noyau exécute tout le code impliqué à partir d'un point de la carte, et lorsqu'il atteint une référence à du code qui n'a pas vraiment été chargé, il le charge - à partir d'une image exécutable sur le disque - même si de manière plus décontractée sens, que l'exécutable (que ce soit le shell, un outil autonome ou une bibliothèque partagée) était déjà "chargé en mémoire".

C'est ce qu'on appelle la pagination de la demande .

boucle d'or
la source
9

En attendant que l'un des poids lourds vienne et donne une perspective historique complète, je vais vous donner ma compréhension plus limitée.

Commandes intégrées comme alias, cd, echoetc font partie de votre coquille ( bash, zsh, kshou autre). Ils sont chargés en même temps que le shell et sont simplement des fonctions internes de ce shell.

terdon
la source
4

J'ai fait l'expérience suivante pour montrer que les commandes intégrées sont en fait chargées dans le cadre de l'exectuable bash. C'est pourquoi ils sont appelés builtins, mais une démo est toujours le meilleur moyen de prouver quelque chose.

Exemple

  1. Démarrez un nouveau bashshell et notez son ID de processus (PID):

    $ bash
    $ echo $$
    6402
    
  2. Dans un deuxième terminal, exécutez la pscommande afin que nous puissions regarder et voir si bashcommence à prendre de la mémoire supplémentaire:

    $ watch "ps -Fp 6402"
    

    La sortie ressemble à ceci:

    Every 2.0s: ps -Fp 6402                        Sat Sep 14 14:40:49 2013
    
    UID        PID  PPID  C    SZ   RSS PSR STIME TTY          TIME CMD
    saml      6402  6349  0 28747  6380   1 14:33 pts/38   00:00:00 bash
    

    REMARQUE: l' utilisation de la mémoire est indiquée avec les colonnes SZ et RSS ici.

  3. Commencez à exécuter des commandes dans le shell (pid 6402):

    Comme vous cdle remarquerez, la mémoire augmente en fait, mais ce n'est pas à cause du cdchargement de l'exécutable en mémoire, mais plutôt parce que la structure de répertoires sur le disque est chargée en mémoire. Si vous continuez cddans d'autres répertoires, vous le verrez augmenter progressivement.

    Every 2.0s: ps -Fp 30208                        Sat Sep 14 15:11:22 2013
    
    UID        PID  PPID  C    SZ   RSS PSR STIME TTY          TIME CMD
    saml     30208  6349  0 28780  6492   0 15:09 pts/38   00:00:00 bash
    

    Vous pouvez faire des tests plus élaborés comme celui-ci:

    $ for i in `seq 1000`; do cd ..; cd 90609;done
    

    Cette commande montera un niveau puis redescendra dans le répertoire 90609 1000 fois. Lorsque vous exécutez cela si vous surveillez l'utilisation de la mémoire dans la psfenêtre, vous remarquerez qu'elle ne change pas. Lors de l'exécution de quelque chose comme ça, aucune utilisation de mémoire supplémentaire ne doit être remarquée.

  4. strace

    Voici un autre tell que nous avons affaire à une fonction intégrée bashplutôt qu'à un véritable exécutable. Lorsque vous essayez et exécutez, strace cd ..vous obtenez le message suivant:

    $ strace cd ..
    strace: cd: command not found
    
slm
la source
3

"commande intégrée" fait référence aux commandes intégrées dans le shell, plutôt que comme des programmes séparés. ls, par exemple, n'est en fait pas une commande intégrée mais un programme distinct. Il sera chargé dans la RAM lors de son appel, sauf s'il est déjà dans le cache disque.

Un exemple de commande intégrée serait printfou cd. Ceux-ci font partie de la coque et sont chargés avec le reste de la coque.

Aucune commande n'est préchargée par défaut, bien que des systèmes aient été créés pour ce faire.

wingedsubmariner
la source