Kiedy wbudowane polecenia są ładowane do pamięci

11

Powiedzmy, że jeśli piszę cdw mojej powłoce. cdW tym momencie jest ładowany z pamięci? Moją intuicją jest to, że te wbudowane polecenia są wstępnie ładowane do pamięci systemowej po załadowaniu jądra, ale ktoś nalegał, że są one ładowane tylko wtedy, gdy faktycznie wywołuję polecenie (naciśnij enter na powłoce). Czy możesz mi powiedzieć, czy istnieje odniesienie, które to wyjaśnia?

Myśliciel
źródło
1
Myślę, że ta odpowiedź pomogłaby ci zrozumieć, chociaż nie jest to duplikat.
cjm
@cjm: Dzięki, to było naprawdę dobre wyjaśnienie do przeczytania.
Myśliciel

Odpowiedzi:

9

Powiedzmy, że jeśli napiszę cd w mojej powłoce. Czy płyta CD jest w tej chwili ładowana z pamięci? Moją intuicją jest to, że te wbudowane polecenia są wstępnie ładowane do pamięci systemowej po załadowaniu jądra, ale ktoś nalegał, że są ładowane tylko wtedy, gdy faktycznie wywołuję polecenie ...

W szerszym ujęciu pozostałe odpowiedzi są poprawne - wbudowane są ładowane z powłoką, autonomiczne są ładowane po wywołaniu. Jednak bardzo kleisty łasica „ktoś” mógłby upierać się, że nie jest to takie proste.

Ta dyskusja dotyczy nieco tego, jak działa system operacyjny, a różne systemy operacyjne działają w różny sposób, ale myślę, że ogólnie rzecz biorąc, prawdopodobnie wszystkie poniższe * prawdy są prawdziwe.

Po pierwsze, „załadowany do pamięci” jest niejednoznacznym zwrotem; tak naprawdę mamy na myśli mapowanie wirtualnej przestrzeni adresowej do pamięci . Jest to istotne, ponieważ „wirtualna przestrzeń adresowa” odnosi się do rzeczy, które mogą wymagać umieszczenia w pamięci, ale w rzeczywistości nie są początkowo: głównie to, co jest faktycznie ładowane do pamięci, to sama mapa - a mapa nie jest terytorium. „Terytorium” byłoby plikiem wykonywalnym na dysku (lub w pamięci podręcznej dysku) i w rzeczywistości większość z nich prawdopodobnie nie jest ładowana do pamięci po wywołaniu pliku wykonywalnego.

Ponadto znaczna część „terytorium” to odniesienia do innych terytoriów (bibliotek współdzielonych), i ponownie, tylko dlatego, że zostały one przywołane, nie oznacza, że ​​są one naprawdę załadowane. Nie są ładowane, dopóki nie zostaną faktycznie użyte, a następnie tylko te części, które faktycznie muszą zostać załadowane, aby jakiekolwiek „użycie” miało się powieść.

Na przykład, oto fragment topwyniku w Linuksie odnoszący się do bashinstancji:

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

113 MB VIRT to wirtualna przestrzeń adresowa odwzorowana w pamięci RAM. Ale RES to faktyczna ilość pamięci RAM zużywanej przez proces - tylko 3,7 kB. Część tego stanowi część wspomnianego wyżej wspólnego terytorium - 1,8 kB SHR. Ale mój /bin/bashdysk ma pojemność 930 kB, a podstawowa biblioteka libc, z którą się łączy (biblioteka współdzielona) jest dwukrotnie większa.

Ta skorupa nic teraz nie robi. Powiedzmy, że wywołuję wbudowane polecenie, które, jak powiedzieliśmy wcześniej, zostało już „załadowane do pamięci” wraz z resztą powłoki. Jądro wykonuje dowolny kod, poczynając od punktu na mapie, a kiedy osiąga odwołanie do kodu, który tak naprawdę nie został załadowany, ładuje go - z obrazu wykonywalnego na dysku - nawet w bardziej swobodnym sens, że plik wykonywalny (czy to powłoka, samodzielne narzędzie, czy wspólna biblioteka) został już „załadowany do pamięci”.

Nazywa się to stronicowaniem na żądanie .

Złotowłosa
źródło
9

Czekając na przybycie jednego z ciężkich graczy i przedstawienie pełnej perspektywy historycznej, dam ci moje bardziej ograniczone zrozumienie.

Wbudowanych komend takich jak alias, cd, echoitp są częścią obudowy ( bash, zsh, kshlub cokolwiek). Są ładowane w tym samym czasie, gdy powłoka jest i są po prostu wewnętrznymi funkcjami tej powłoki.

terdon
źródło
4

Zrobiłem następujący eksperyment, aby pokazać, że wbudowane polecenia są w rzeczywistości ładowane jako część tego, co możliwe bash. Dlatego nazywane są wbudowanymi, ale wersja demo jest zawsze najlepszym sposobem na udowodnienie czegoś.

Przykład

  1. Uruchom nową bashpowłokę i zanotuj jej identyfikator procesu (PID):

    $ bash
    $ echo $$
    6402
    
  2. W drugim terminalu uruchom pspolecenie, abyśmy mogli zobaczyć, czy bashzacznie zajmować dodatkową pamięć:

    $ watch "ps -Fp 6402"
    

    Dane wyjściowe wyglądają następująco:

    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
    

    UWAGA: Wykorzystanie pamięci pokazano tutaj z kolumnami SZ i RSS.

  3. Rozpocznij uruchamianie poleceń w powłoce (pid 6402):

    Gdy będziesz w cdpobliżu, zauważysz, że pamięć faktycznie rośnie, ale nie dzieje się tak dlatego, że plik wykonywalny cdjest ładowany do pamięci, a raczej dlatego, że struktura katalogów na dysku ładuje się do pamięci. Jeśli będziesz przeglądać cdinne katalogi, zobaczysz, że stopniowo rośnie.

    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
    

    Możesz wykonać bardziej skomplikowane testy, takie jak to:

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

    To polecenie przejdzie na wyższy poziom, a następnie z powrotem do katalogu 90609 1000 razy. Podczas uruchamiania, jeśli monitorujesz użycie pamięci w psoknie, zauważysz, że się to nie zmienia. Podczas uruchamiania czegoś takiego nie należy zauważać dodatkowego użycia pamięci.

  4. strace

    Oto kolejna informacja, że ​​mamy do czynienia z wbudowaną funkcją bashzamiast z rzeczywistym plikiem wykonywalnym. Podczas próby uruchomienia strace cd ..pojawi się następujący komunikat:

    $ strace cd ..
    strace: cd: command not found
    
slm
źródło
3

„polecenie wbudowane” odnosi się do poleceń wbudowanych w powłokę, a nie jako osobne programy. ls, na przykład tak naprawdę nie jest wbudowanym poleceniem, ale osobnym programem. Zostanie załadowany do pamięci RAM po wywołaniu, chyba że znajduje się już w pamięci podręcznej dysku.

Przykładem wbudowanego polecenia może być printflub cd. Są one częścią powłoki i są ładowane wraz z resztą powłoki.

Domyślnie żadne polecenia nie są wstępnie ładowane, chociaż systemy zostały utworzone w tym celu.

wingedsubmariner
źródło