« Отговор #6 -: Oct 02, 2008, 16:49 »
@teleport, не е тъпо и е вярно ама от гледна точка на адресното пространство на процеса, а не от гледна точка на утилизирането на физическата памет въобще.
Значи физическата памет на 32-битова архитектура директно може да се адресира само до 1-вия гигабайт. Тъй като се "отцепват" 128 мегабайта за мапиране на по-горна памет, всъщност се адресират до 896 мегабайта физическа памет. По дефолт, ядрото може директно да адресира и до 1ГБ виртуална памет.
Когато си с CONFIG_HIGHMEM можеш да мапираш "горната" памет и тогава дефакто примерно ако имаш 1ГБ физическа РАМ можеш да използваш и последните 128 мегабайта, мапирайки ги при желание върху "долните" 896 мегабайта. С PAE (CONFIG_HIGHMEM64) можеш да мап-ваш до 64 гигабайта памет (но не и директно да я адресираш и достъпваш, има едни таблици, те пазят кои страници от горната памет върху кои адреси от долната се мап-ват). Това от гледна точка на ядрото.
От гледна точка на адресното пространство на процеса, може да се адресират до 4 гигабайта, независимо от режима. Тази памет се цепи на страници (по 4кб обикновено) и тези страници се мапират или върху физическата памет, или върху суоп-а. За целта всеки процес си има pagetable, първите 128 мегабайта от адресното пространство на процеса обикновено, затова програмния код се зарежда от 0х08048000 нагоре. Ако процесът достъпи памет, мапирана върху суоп-а се случва page fault, процесът се прекъсва и ядрото вади страницата от диска и я слага във физическата памет, променя мапировката, така че за процеса тази памет е на същия адрес, но дефакто се намира другаде.
Сега защо процесът може да ползва до 3ГБ, въпреки че адресира до 4ГБ? Ами просто. В адресното пространство на процеса се мап-ва цялото виртуално адресно пространство на ядрото (1ГБ както казах). Повечето от тази памет не може да се чете, страниците са маркирани без атрибут "r" и достъпването им води до segmentation fault за програмата.
Има варианти това да изглежда по различен начин, примерно виртуалното адресно пространство на ядрото може да се увеличи до 2ГБ. Тогава обаче процесът вече като го мап-не може да използва само 4-2=2ГБ памет. Това се нарича 2G/2G split и може да бъде полезно ако примерно имаш много натоварен рутер дето прави QoS и в същото време нямаш работещи процеси дето да изискват много памет. С това трябва да знаеш че със сигурност ще разкажеш играта на всички java виртуални машини, wine и други неща дето имат навика да резервират цялата си възможна памет и да си правят собствен мениджмънт на паметта, уповавайки се на това, че ако имат възможност, ще адресират до 3ГБ памет.
Но да, в най-добрият случай на 32-битова архитектура, реално погледнато един процес може да задели максимум 3ГБ памет. Иначе може да адресира и евентуално чете максимум 4ГБ. Със или без PAE, това няма значение.
Апропо, нещата с 64-битовите архитектури стоят по подобен начин, просто там лимитите са много по-големи, затова 3G/1G split-а изобщо не ти прави проблеми, дори да имаш 512 гигабайта физическа памет.