Скажімо, якщо я ввожу компакт-диск у своїй оболонці. Чи завантажується компакт-диск із пам'яті в цей момент? Моя інтуїція полягає в тому, що ці вбудовані команди попередньо завантажуються в системну пам'ять після завантаження ядра, але хтось наполягав, що вони завантажуються лише тоді, коли я фактично викликаю команду ...
В широкому розумінні інші відповіді правильні - вбудовані пристрої завантажуються оболонкою, автономні алони завантажуються при виклику. Однак дуже чіткий невідомий «хтось» може наполягати, що це не так просто.
Ця дискусія дещо про те, як працює ОС, і різні операційні системи працюють по-різному, але я думаю, загалом, наступне, мабуть, стосується всіх сучасних нікс.
По-перше, "завантажений в пам'ять" - неоднозначна фраза; насправді, про що ми маємо на увазі, це віртуальний адресний простір, відображений у пам'яті . Це важливо, оскільки "віртуальний адресний простір" відноситься до речей, які, можливо, потрібно буде помістити в пам'ять, але насправді це не спочатку: в основному те, що насправді завантажується в пам'ять, - це сама карта - а карта - це не територія. "Територія" була б виконуваною на диску (або в кеш-диску), і насправді більшість із них, ймовірно, не завантажуються в пам'ять, коли ви викликаєте виконуваний файл.
Крім того, значна частина "території" - це посилання на інші території (спільні бібліотеки), і знову ж таки, саме те, що на них посилалися, не означає, що вони теж завантажені. Вони не завантажуються до тих пір, поки не будуть фактично використані, а потім лише ті шматки, які насправді потрібно завантажувати, щоб будь-яке "використання" було успішним.
Наприклад, ось фрагмент top
виводу на Linux з посиланням на bash
екземпляр:
VIRT RES SHR S %CPU %MEM TIME+ COMMAND
113m 3672 1796 S 0.0 0.1 0:00.07 bash
ВІРТ 113 Мб - це віртуальний адресний простір, який відображається в ОЗУ. Але ВДЕ - це фактична кількість оперативної пам’яті, спожитого процесом, - лише 3,7 кБ. І з цього частина є частиною згаданої вище загальної території - 1,8 кБ ШР. Але мій /bin/bash
на диску 930 кБ, і базовий libc, на який він посилається (спільна ліб), знову вдвічі більший.
Ця оболонка зараз нічого не робить. Скажімо, я викликаю вбудовану команду, про яку ми говорили раніше, вже "завантажена в пам'ять" разом з рештою оболонки. Ядро виконує будь-який код, починаючи з точки на карті, і коли він доходить посилання на код, який насправді не завантажений, він завантажує його - з виконуваного зображення на диску - навіть у більш випадковій формі сенс, що виконуваний файл (будь то оболонка, автономний інструмент або спільна бібліотека) вже "завантажений у пам'ять".
Це називається пейджингом попиту .