Quando vengono caricati nella memoria i comandi integrati


11

Diciamo se scrivo cdnella mia shell. È cdcaricato dalla memoria in quel momento? La mia intuizione è che questi comandi integrati sono pre-caricati nella memoria di sistema dopo che il kernel è stato caricato, ma qualcuno ha insistito sul fatto che sono caricati solo quando invoco effettivamente il comando (premere invio su una shell). Potresti dirmi se c'è un riferimento che spiega questo?


1
Penso che questa risposta possa aiutarti a capire, anche se non è del tutto un duplicato.
cjm

@cjm: Grazie è stata davvero una buona spiegazione da leggere.
Pensatore

Risposte:


9

Diciamo che se scrivo cd nella mia shell. Il cd è stato caricato dalla memoria in quel momento? La mia intuizione è che questi comandi integrati sono precaricati nella memoria di sistema dopo che il kernel è stato caricato, ma qualcuno ha insistito sul fatto che sono caricati solo quando invoco effettivamente il comando ...

In termini generali le altre risposte sono corrette: gli built-in vengono caricati con la shell, gli stand-alone vengono caricati quando vengono invocati. Tuttavia, un "qualcuno" molto appiccicoso potrebbe insistere sul fatto che non è così semplice.

Questa discussione riguarda in qualche modo il funzionamento del sistema operativo e i diversi sistemi operativi funzionano in modi diversi, ma penso che in generale quanto segue sia probabilmente vero per tutti i * nix contemporanei.

Innanzitutto, "caricato nella memoria" è una frase ambigua; veramente ciò a cui ci riferiamo è che il suo spazio di indirizzi virtuale è mappato nella memoria . Ciò è significativo perché "spazio di indirizzi virtuali" si riferisce a elementi che potrebbero dover essere inseriti in memoria, ma in realtà non lo è inizialmente: principalmente ciò che viene effettivamente caricato in memoria è la mappa stessa - e la mappa non è il territorio. Il "territorio" sarebbe l'eseguibile su disco (o nella cache del disco) e, in effetti, la maggior parte di ciò probabilmente non viene caricata in memoria quando si richiama un eseguibile.

Inoltre, gran parte del "territorio" fa riferimento ad altri territori (librerie condivise) e, di nuovo, solo perché sono stati indicati non significa che siano realmente caricati. Non vengono caricati fino a quando non vengono effettivamente utilizzati, e quindi solo i pezzi che devono effettivamente essere caricati per qualsiasi "utilizzo" abbia successo.

Ad esempio, ecco uno snippet di topoutput su linux che fa riferimento a bashun'istanza:

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

VIRT da 113 MB è lo spazio di indirizzi virtuale, che è mappato nella RAM. Ma RES è la quantità effettiva di RAM consumata dal processo - solo 3,7 kB. E di ciò, alcuni fanno parte del territorio condiviso sopra citato - 1,8 kB SHR. Ma il mio /bin/bashsu disco è 930 kB e la libc di base a cui si collega (una lib condivisa) di nuovo doppiamente grande.

Quella shell non sta facendo nulla in questo momento. Diciamo che invoco un comando integrato, che abbiamo detto prima era già "caricato in memoria" insieme al resto della shell. Il kernel esegue qualunque codice sia coinvolto a partire da un punto della mappa e quando raggiunge un riferimento a un codice che non è stato realmente caricato, lo carica - da un'immagine eseguibile su disco - anche se in modo più casuale intendo, quel file eseguibile (che si tratti della shell, di uno strumento autonomo o di una libreria condivisa) era già "caricato in memoria".

Questo è chiamato paging della domanda .


9

Mentre aspetto che uno dei pesi massimi arrivi e dia una prospettiva storica completa, ti darò la mia comprensione più limitata.

Built-in comandi come alias, cd, echoecc fanno parte della vostra shell ( bash, zsh, ksho qualsiasi altra cosa). Vengono caricati contemporaneamente alla shell e sono semplicemente funzioni interne di quella shell.


4

Ho fatto il seguente esperimento per dimostrare che i comandi integrati sono effettivamente caricati come parte dell'esecutivo bash. Ecco perché si chiamano builtin, ma una demo è sempre il modo migliore per provare qualcosa.

Esempio

  1. Avviare una nuova bashshell e prendere nota dell'ID processo (PID):

    $ bash
    $ echo $$
    6402
    
  2. In un secondo terminale esegui il pscomando in modo che possiamo vedere e vedere se bashinizia a occupare memoria aggiuntiva:

    $ watch "ps -Fp 6402"
    

    L'output è simile al seguente:

    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
    

    NOTA: l' utilizzo della memoria viene mostrato con le colonne SZ e RSS qui.

  3. Inizia a eseguire comandi nella shell (pid 6402):

    Mentre cdti accorgerai che la memoria aumenta, ma questo non è dovuto al fatto che l'eseguibile cdviene caricato in memoria, piuttosto perché la struttura della directory sul disco viene caricata in memoria. Se continui ad cdaccedere ad altre directory, lo vedrai incrementalmente continuare a salire.

    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
    

    Puoi fare test più elaborati come questo:

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

    Questo comando eseguirà il cd up di un livello e quindi tornerà alla directory 90609 1000 volte. Durante l'esecuzione se si controlla l'utilizzo della memoria nella psfinestra, si noterà che non cambia. Durante l'esecuzione di qualcosa del genere, non si dovrebbe notare alcun ulteriore utilizzo della memoria.

  4. strace

    Ecco un altro che dice che abbiamo a che fare con una funzione integrata bashpiuttosto che con un vero eseguibile. Quando si tenta di eseguire strace cd .., viene visualizzato il seguente messaggio:

    $ strace cd ..
    strace: cd: command not found
    

3

"comando integrato" si riferisce ai comandi integrati nella shell, piuttosto che come programmi separati. ls, ad esempio, in realtà non è un comando integrato ma un programma separato. Verrà caricato nella RAM quando viene invocato, a meno che non sia già nella cache del disco.

Un esempio di comando incorporato sarebbe printfo cd. Questi fanno parte della shell e vengono caricati insieme al resto della shell.

Nessun comando è precaricato per impostazione predefinita, sebbene i sistemi siano stati creati per farlo.

Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.