Віртуальная памяць

**Віртуа́льная па́мяць** — гэта схема арганізацыі памяці кампутара, пры якой праграмнае забесьпячэньне ўяўляе адрасную прастору кампутара бесьперапыннай і аднастайнай.

## Гісторыя стварэньня
У першых кампутарах памяць была вельмі малая па аб’ёме і да таго ж каштавала вельмі дорага. Адзін з самых хуткадзейных кампутараў таго часу — IBM-650 (канец 1950-х гадоў) — утрымоўваў усяго 2000 словаў памяці. Адзін зь першых кампілятараў ALGOL быў напісаны для кампутара з аб’ёмам памяці ўсяго 1024 словы. Старажытная сыстэма з падзелам часу выдатна працавала на кампутары PDP-1, агульны аб’ём памяці якога складаў усяго 4096 18-разрадных словаў для апэрацыйнай сыстэмы і праграм карыстальніка. У тыя часы праграмісты марнавалі вельмі шмат часу, спрабуючы зьмясьціць свае праграмы ў малюсенькую памяць. Часта прыходзілася выкарыстоўваць маруднейшыя альгарытмы толькі таму, што хутчэйшыя не атрымоўвалася разьмясьціць у памяці кампутара.

У 1961 годзе група дасьледнікаў з Манчэстэра (Ангельшчына) прапанавала мэтад аўтаматычнага выкананьня працэсу накладаньня розных частак памяці, пры якім праграміст мог наогул не думаць аб гэтым працэсе. Гэты мэтад, у аснове якога, як цяпер кажуць, ляжыць выкарыстаньне віртуальнай памяці, меў відавочную перавагу, паколькі вызваляў праграміста ад масы нуднай працы. Упершыню гэты мэтад быў ужыты ў шэрагу кампутараў, выпушчаных у 60-я гады. Да пачатку 70-х гадоў віртуальная памяць была рэалізаваная ў большасьці кампутараў. У цяперашні час нават кампутары на адной мікрасхеме, у тым ліку Pentium 4 і UltraSPARC III, маюць вельмі складаныя сыстэмы віртуальнай памяці.

## Старонкавая арганізацыя памяці
Згодна з канцэпцыяй віртуальнай памяці, уся фізычная і віртуальная памяць кампутара разьбіваецца на роўныя часткі, якія завуцца старонкі. Дзякуючы наяўнасьці віртуальнай памяці фізычная памяць і яе абмежаваньне перастаюць быць перашкодаю для праграміста.

Праграмы пішуцца так, быццам у апэратыўнай памяці хапае месца для разьмяшчэньня ўсёй віртуальнай адраснай прасторы, нават калі гэта не адпавядае рэчаіснасьці. Праграмы могуць загружаць словы зь віртуальнай адраснай прасторы або запісваць словы ў віртуальную адрасную прастору, нягледзячы на тое, што на самай справе фізычнай памяці для гэтага можа не хапіць. Праграміст можа пісаць праграмы, нават не ўсьведамляючы, што існуе віртуальная памяць. Проста ствараецца такое ўражаньне, што аб’ём памяці дадзенага кампутара досыць вялікі.

Віртуальнай памяці патрабуецца фізычная памяць для захоўваньня ўсёй праграмы і ўсіх дадзеных. Копію праграмы, якая захоўваецца ў фізычнай памяці, зручней разглядаць як арыгінал, а фрагмэнты, якія запісваюцца ў апэратыўную памяць, — як копіі. Натуральна, арыгінал у такім разе павінен апэратыўна абнаўляцца. Калі зьмены ўносяцца ў копію праграмы ў апэратыўнай памяці, яны ў канчатковым выніку павінны быць адлюстраваныя ў арыгінале.

Віртуальная адрасная прастора разьбіваецца на шэраг старонак роўнага памеру, звычайна ад 512 байт да 64 Кбайт, хоць часам сустракаюцца старонкі па 4 Мбайт. Памер старонкі заўсёды павінен быць ступеньню двойкі. Фізычная адрасная прастора таксама разьбіваецца на часткі роўнага памеру такім чынам, каб кожная такая частка апэратыўнай памяці зьмяшчала роўна адну старонку. Гэтыя часткі апэратыўнай памяці завуцца старонкавымі кадрамі.

## Выклік старонак па патрабаваньні і працоўнае мноства

Віртуальная старонка, да якой адбываецца зварот, не заўжды знаходзіцца ў апэратыўнай памяці, паколькі ў апэратыўнай памяці нядосыць месца для ўсіх віртуальных старонак. Пры звароце да адрасу старонкі, якой няма ў апэратыўнай памяці, адбываецца **памылка адсутнасьці старонкі**. У выпадку такой памылкі апэрацыйная сыстэма павінна прачытаць патрэбную старонку з дыску, увесьці новы адрас фізычнай памяці ў табліцу старонак, а затым паўтарыць каманду, якая выклікала памылку.

Такі мэтад працы зь віртуальнай памяцьцю завецца **выклікам старонак па патрабаваньні** (demand paging). Такі выклік старонак нагадвае кармленьне немаўля па патрабаваньні (у супрацьлегласьць кармленьню па раскладзе): калі немаўля крычыць, вы яго корміце. Пры выкліку старонак па патрабаваньні старонкі пераносяцца ў апэратыўную памяць толькі ў выпадку неабходнасьці, але не раней.

Альтэрнатыўны падыход заснаваны на назіраньні, што шматлікія праграмы зьвяртаюцца да адраснай прасторы нераўнамерна. Звычайна большасьць зваротаў адносяцца да невялікай колькасьці старонак. Гэта завецца прынцыпам лякальнасьці. Пры звароце да памяці можна выклікаць каманду, выклікаць зьвесткі або захаваць зьвесткі. У кожны момант часу існуе набор старонак, якія выкарыстоўваліся пры апошніх зваротах. Вось гэты набор старонак і завецца **працоўным мноствам**.

= Недахопы =

### Фрагмэнтацыя памяці
У выніку разьбіцьця памяці на старонкі ўзьнікае праблема фрагмэнтацыі памяці. Некаторая праграма, якая выкарыстоўвае n старонак, можа ня выкарыстаць усю прастору памяці, у выніку чаго на апошняй n-ай старонцы ўзьнікне пустая прастора.

Для зьмяншэньня эфэкту фрагмэнтацыі распрацаваны шэраг альгарытмаў.

Калі памер старонкі складае n байт, то сярэдняя нявыкарыстаная прастора апошняй старонкі праграмы будзе роўна n/2 байт. Такім чынам, каб зьвесьці да мінімуму аб’ём бескарыснай прасторы, старонкі павінны быць невялікімі. Аднак пры маленькіх старонках патрабуецца шмат старонак і вялікая табліца старонак. Калі табліца старонак захоўваецца апаратна, то для захоўваньня вялікай табліцы старонак трэба шмат рэгістраў, што падвышае кошт кампутара. Акрамя таго, для праграмы на загрузку і захаваньне гэтых рэгістраў спатрэбіцца больш часу.

### Бясьпека
Істотнай праблемай зьяўляецца неабходнасьць вырашыць: якім праграмам можна дазволіць доступ да пэўных старонак, а якім — не. Для гэтага выкарыстоўваюцца розныя падыходы, у тым ліку сыстэма бясьпекі PL ад карпарацыі Intel.

### Палітыка замяшчэньня старонак
У некаторых выпадках віртуальнай памяці можа проста не хапіць. У такім выпадку непатрэбныя старонкі мусяць выдаляцца і замяняцца на неабходныя цякучым задачам. Для вырашэньня гэтай праблемы існуюць некалькі альгарытмаў:

# LRU (Least Recently Used — найдаўжэй не выкарыстоўваўся);
# FIFO (First-in First-out — першым увайшоў — першым сышоў).

## Сэгмэнтацыя
Сэгмэнтацыя — мноства незалежных адрасных прастораў. Гэта больш глыбокі падыход да выкарыстаньня віртуальнай памяці.

Кожны сэгмэнт складаецца зь лінейнай пасьлядоўнасьці адрасоў ад 0 да якога-небудзь дапушчальнага максымуму. Розныя сэгмэнты могуць мець розную даўжыню (звычайна так і бывае). Больш за тое, даўжыня сэгмэнту можа зьмяняцца падчас выкананьня праграмы. Даўжыня стэкавага сэгмэнту можа павялічвацца кожны раз, калі штосьці зьмяшчаецца ў стэк, і памяншацца, калі штосьці выштурхваецца са стэку.

### Рэалізацыя сэгмэнтацыі
Рэалізаваць разьбіцьцё адзінай адраснай прасторы на нейкае мноства можна з дапамогаю **старонкавай арганізацыі** ці **зьнешняй фрагмэнтацыі**.

Зьнешняя фрагмэнтацыя дазваляе сьціскаць сэгмэнты, вызваляючы пустоты для новых сэгмэнтаў. Таксама можна выкарыстаць альгарытм аптымальнай падгонкі, які шукае найменшыя пустоты ў прасторы адрэсаў і разьмяшчае ў іх найменшыя сэгмэнты.

Старонкавая арганізацыя ўпершыню была распрацаваная для сыстэмы MULTICS (Multiplexed Information and Computing Service) і патрабуе наяўнасьці табліцы дэскрыптараў, каталёгу старонак і канкрэтнай старонкі. Дэскрыптар спасылаўся на табліцу старонак, што дазваляла разьбіваць на старонкі кожны сэгмэнт звычайным спосабам.

Падобную схему выкарыстоўваюць працэсары Intel пачынаючы з 386, у тым ліку і віртуальная памяць працэсара Pentium IV.

## Крыніцы