| Управління своп-файлом
Для зберігання образів модифікованих сторінок система повинна виділити
якийсь простір на диску. Для цього може використовуватися як розділ
диска, так і файл, місце для якого виділяється нарівні з файлами даних.
Більшість сучасних систем можуть використовувати як той, так і інший
методи, і підтримує динамічне підключення і відключення своп-файлів
і своп-розділів.
За
наявності в системі декількох дисків рекомендується розділити своп-простір між
всіма (або хоч би між менш використовуваними) дисками. Річ у тому, що
операції читання і запису вимагають часу на позиціювання прочитуючої голівки.
Поки один накопичувач пересуває голівку, другою сповна може передавати
дані. Зрозуміло, що лінійного зростання продуктивності із збільшенням числа
дисків в такий спосіб не отримати: завжди є вірогідність, що
всі необхідні дані виявляться на одному диску, та ще і знаходяться в різних
місцях, але все одно виграш в більшості випадків виявляється значним.
В ті часи, коли комп'ютери були великими, для свопу часто використовувалися
не диски, а спеціальні пристрої, магнітні барабани. На відміну від диска,
який має одну або, рідше, декілька голівок читання-запису, барабан
мав по одній голівці на кожну доріжку. Звичайно, це підвищувало вартість
пристрою, але повністю виключало втрати часу на позиціювання
(мал. 5.23).

Мал. 5.23. Магнітний диск і магнітний барабан
У своп-файл потрапляють лише сторінки, які змінилися з моменту завантаження процесу.
Якщо ОС використовує абсолютне завантаження або позиии-онно-независимып код,
код, що виконується, не відрізняється від свого образу в завантажувальному файлі,
тому сторінки коди цілком можна підкачувати звідти, і немає жодної необхідності
копіювати їх в своп. Часто при завантаженні програми система поміщає в
пам'ять лише сторінку, на яку вказує стартова адреса, а весь останній
використовуваний код і дані підвантажуються механізмом сторінкового обміну.
При
завантаженні даних, що статично ініціалізували, зазвичай використовується
стратегія сору-on-write (копіювання при модифікації): спочатку сторінка
підкачується з файлу. Якщо вона не буде модифікована і її оголосять
жертвою, то при повторному зверненні її знову підвантажать з того ж файлу
(мал. 5.24). Лише якщо сторінка буде змінена, їй виділять місце в своп-файлі.

Мал. 5.24. Копіювання при модифікації
Якщо ж використовується відносне завантаження або та або інша форма збірки у момент
завантаження (бібліотеки, що розділяються, або DLL), при завантаженні коди відбувається
перенастроювання адрес. В цьому випадку можливі два підходи: копіювати
код, що перенастроює, в своп або виробляти перенастроювання заново
після кожної сторінкової відмови.
Відображення файлів в пам'ять в Unix
Системи сімейства Unix надають користувачам доступ до механізмів,
використовуваних при завантаженні програм, у вигляді системного виклику гол-ар. Цей
виклик відображує ділянку файлу в пам'ять. Відображення можливе в двох режимах:
MAP_SHARED зміни в пам'яті відображуються у файле—
таким чином mmap можна використовувати для реалізації пам'яті, що
розділяється, і MAP_PRIVATE (відповідно, зміни
пам'яті у файлі не відображуються — при цьому змінені сторінки копіюються
в своп-файл).
Широко
використовується виділення пам'яті за допомогою відображення псевдофайлу /dev/zero
(файл безконечної довжини, що складається з одних нулів) в пам'ять
в режимі MAP_PRIVATE.
Навіть коли місце під своп-файл виділяється динамічно, система зазвичай
надає можливість обмежувати його зростання. Біля інтерактивних систем
при наближенні до кордону ємкості своп-файлу система часто починає
видавати попередження користувачеві. Проте основним виглядом реакції на
переповнювання або перевищення лімітів зростання своп-файлу є відмова виділяти
пам'ять прикладним програмам. Тому грамотно написані програми завжди
повинні перевіряти, чи нормально завершився запит на виділення пам'яті, і по
можливості розумно обробляти ненормальне завершення. Це потрібно не лише у
тому випадку, коли програма переноситиметься в систему без виртуатьной пам'яті,
але і в сповна штатній (хоча і відносно рідкої) ситуації переповнювання
свопу.
Інколи, втім, система може виділяти пам'ять (точніше, не пам'ять, а лише
адресний простір) програмам не оглядаючись на те, скільки є
вільного свопу. Ета досить небезпечна стратегія, звана overcommit, на
перший погляд здається безглуздою або корисною лише в дуже спеціальних
випадках, наприклад при використанні розріджених масивів. Насправді ця
стратегія виправдана і тоді, коли ми можемо бути упевнені, що більшість
виділених процесу сторінок ніколи не будуть використані, наприклад, при
широкому вживанні стратегії сору-on-write.
Overcommit в Unix
У
системах
сімейства Unix копіювання при записі застосовується не лише при завантаженні
сегментів даних програм і відображень файлів в пам'ять, але і
при створенні завдань. Системний виклик fork (детальніше обговорювався в главі 3)
створює повну копію адресного простору процесу, що виконав цей
виклик. Фізичного копіювання, природно, не відбувається. Замість цього
система відображує пам'ять батьківського процесу в адресний простір нащадка
і встановлює захист від запису на всі сторінки обох завдань. Коли
якась із завдань намагається здійснити запис, відповідна сторінка фізично
копіюється і запис здійснюється вже в копію. Більшість породжених
завдань виконують системний виклик exec незабаром після створення, змінивши
лише декілька змінних в своєму адресному просторі. При такому стилі
роботи з пам'яттю, дійсно, багато сторінок, що виділяються, не використовуються
ніколи, а більшість з використовуваних лише прочитуються, тому overcommit
є стандартною стратегією виділення пам'яті в Unix.
|