IMPLEMENTAREA GESTIUNII MEMORIEI -...
Transcript of IMPLEMENTAREA GESTIUNII MEMORIEI -...
IMPLEMENTAREA
GESTIUNII MEMORIEI
SERIAN BIANCA
JICA ANDREEA
SEPTAR OZGEAN
432 A
CUPRINS
1. Introducere
Serian Bianca
2. Tipuri de memorie
3. Gestiunea memoriei
3.1. Gestiunea memoriei interne
3.2. Gestiunea memoriei externe
4. Spațiul de adresa al unui proces
5. Mecanismele de gestionare a memoriei la Windows
6. Alocarea/Dezalocarea memoriei
6.1. Alocarea memoriei la Windows
6.2. Alocarea memoriei la Linux
6.3. Dezalocarea memoriei
Jica Andreea
7. Paginarea memoriei
7.1. Maparea adreselor
8. Algoritmul de inlocuire a paginilor: windows si linux
8.1. Algoritmul optim de inlocuire a paginilor (teoretic)
8.2. Algoritmul Not Recently Used (NRU)
8.3. First-in, First-out (FIFO)
8.4. Second Chance
8.5. Clock
8.6. Least Recently Used (LRU)
8.7 Algoritmul RANDOM
8.8. Not Frequently Used
8.9. Aging
Septar Ozgean
9. Securitatea si protectia memoriei
9.1 Problema securitatii
9.2 Notiuni si niveluri de securitate
9.3 Securitatea Sistemului de Operare - Securitatea resurselor – Memoria
9.4 Metode si clasificari de securitate si protectie
9.5 Concluzii
1.Introducere
Cresterea puterii de calcul si a spatiului adreselor la microprocesoarele moderne a
condus la extinderea gamei de aplicatii, incluzind cimpuri de tipul sistemelor
multiutilizator cu functionare in timp real, pe timpuri rezervate doar calculatoarelor mari
sau minicalculatoarelor. Realizarea acestor aplicatii sofisticate nu se poate face lasind
gestionarea memoriei in sarcina unui singur programator, fie el foarte bun, asa cum se
intimpla in cazul microprocesoarelor de 8 biti. In schimb, se impune realizarea gestionarii
automate a resurselor de memorie de catre un sistem de operare adecvat, fapt ce are ca
efect o mai buna utilizare a spatiului disponibil.
Ideile ce stau la baza implementarii mecanismelor de gestiune a memoriei nu sint
noi, ci sint imprumutate din solutiile folosite in calculatoare mari sau minicalculatoare.
Utilizarea rationala a memoriei se realizeaza prin luarea in considerare a urmatoarelor :
- exista mai multe tipuri de memorie, cu diverse viteze si costuri pe bit (cum sunt cele cu semiconductoare si cele magnetice). In general, capacitatea memoriilor rapide este limitata de cost sau posibilitati tehnologice, in timp ce memoriile ieftine au timpi lungi de acces;
- intr-un sistem complex, asa cum este calculatorul multiprogramat functionind prin divizarea timpului, nu este necesara pastrarea simultanaa tuturor programelor in memoria primara, deoarece numai cateva dintre acestea sunt gata de rulare, in timp ce altele pot astepta terminarea unor operatii I/O sau pot fi temporar blocate.
In general este convenabil sa consideram ca sistemul de memorie este alcatuit din mai multe subsisteme, cu capacitati diferite si timpi de acces diferiti. Intr-o astfel de configurare mecanismele de gestiune a memoriei vor distribui informatia intre diversele tipuri de memorie, incercind sa pastreze datele si programele la care accesul este mai frecvent in memoriile mai rapide, restul informatiilor fiind plasat in memoriile mai lente.
Desigur, alocarea memoriei nu este statica, intrucit, in cele din urma, sistemul va prelucra toate informatiile memorate. Deci, datele si programele vor fi mutate dintr-o zona de memorie in alta. Fluxul acestor informatii poate fi controlat de catre programator, sistemul de operare, hardware sau o combinatie a tuturor acestor factori. Fiecare din ei poate gestiona un anumit subsistem al memoriei.
2.TIPURI DE MEMORIE
Ierarhizarea memoriei
Memoria unui sistem de calcul trebuie sa satisfaca mai multe cerinte,
adeseacontradictorii: capacitate mare, timp de acces mic, cost rezonabil si
dimensiunireduse. Aceste cerinte nu pot fi indeplinite simultan de un singur tip de
memorie.
Cu tehnologia actuala se pot realiza memorii de mare viteza, dar de capacitate
mica (RAM static), memorii de capacitate mare, dar de viteza medie (variante dememorii
DRAM) sau memorii de capacitate foarte mare, dar cu timp de accesridicat (memorii
externe pe suport magnetic sau optic).
In sistemele de calcul performante, spatiul de memorare este ierarhizat pemai
multe nivele, cu scopul de a beneficia de avantajele oferite de diverse tipuri dememorii.
Un sistem de calcul cu memorie organizata ierarhizat poate echilibradiferentele de
vitezaintre componentele sistemului (CPU, memorie, discuri) .
Intr-o astfel de arhitectura, memoria este organizata pe patru niveluri:
registrele CPU;
memoria cache (MC);
memoria principala sau operativa (MP);
memoria virtuala (MV).
Registrele CPU sunt direct adresabile de catre ALU.
Memoria cache (rapida) este cea mai apropiata de CPU, ceea ce impune catimpul
de acces sa fie mic, capacitatea fiind limitata. Aici sunt pastrate instrucaiunile si datele cu
probabilitatea cea mai mare de a fi utilizate intr-o proximitate de timp.
Fig. 1. Memoria cache
Memoria cache pe chip.Acest nivel, nivelul 1 al memoriei, este mai lent decat
registrele si necesita unele circuite de interfata; totusi, ea este mai rapida decat memoria
din exteriorul circuitului. La acest nivel inca persista distinctia intre date, cod si
informatii de gestiune a memoriei.
Memoria cache pe circuit destinata programului este, uneori, organizata ca o stiva
de tip FIFO, al carei varf este constituit de registrul instructiunii. Aceasta organizare
simpla apare ca urmare a modului aproape liniar al extragerii instructiunilor (perturbarile
- create de executia instructiunilor de salt). Deci, exista o probabilitate ridicata ca
urmatorul cuvant de cod ce trebuie sa fie extras sa se afle la adresa urmatoare.
Instructiunile de salt distrug traseul liniar prin spatiul de adresare si videaza stiva.
Este necesara aducerea de noi cuvinte de cod din memoria externa, deci dispare, pentru
scurt timp, efectul favorabil al memoriei cache pe circuit. Instructiunile necesita un
anumit timp pentru a fi executate in interiorul CPU, iar unitatea de gestiune a tamponului
de memorie umple stiva FIFO mai rapid decat este vidata de catre CPU, care extrage
instructiuni. Deci, dupa executia unei instructiuni de salt, sirul de asteptare in interiorul
circuitului a instructiunilor se reface.
Poate aparea un conflict intre CPU, care trebuie sa execute un ciclu de
citire/scriere a memoriei externe, si unitatea de gestiune a stivei FIFO, care trebuie sa
execute un ciclu de citire din memorie pentru a completa sirul de instructiuni. In astfel de
situatii ciclul necesar prelucrarii de date este prioritar.
Accesul la date este mai putin predictibil decat cel pentru cod, astfel incat
memoria cache pe circuit este organizata ca o memorie cu acces aleator, compusa dintr-o
parte de date si o alta de eticheta (tag).
Memoria “Tag” contine informatia corespunzatoare adresei CPU utilizata pentru
accesul la date.Memoria “Data” cuprinde valorile datelor.
Fig. 2. Organizarea generala a memoriei cache
Implementarea memoriei cache pe circuit ridica un numar de probleme
arhitecturale:
memoria TAG este mare comparativ cu memoria DATA, deci se consuma
o mare arie de siliciu pentru gestiunea memoriei.
studii efectuate prin simulare au aratat ca introducerea memoriei cache pe
circuit creste, in loc sa descreasca, viteza ceruta pentru transferul prin frontiera
circuitului.
Tehnica de tip cache este folosita si pentru a memora informatiile cu cea mai
ridicata fracventa de utilizare, destinate gestiunii memoriei in acelasi circuit cu CPU sau
intr-un circuit destinat special gestiunii memoriei (memory management unit - MMU).
O astfel de unica memorie cache este comandata pe baza principiului LRU (least
recently used - cea mai veche informatie folosita). Nu toate mecanismele de comanda a
memoriei cache pe circuit sunt necontrolabile prin program, dar ele sunt implementate
prin mijloace hardware si prezenta lor tinde sa fie transparenta fata de programator.
Fig. 3. Operarea unitatii de comanda a memoriei cache
Memoria cache pe placa
Aceleasi motive care justifica introducerea de memorii cache pe circuit recomanda
realizarea lor pe aceeasi placa a CPU:
intarzierea introdusa de circuitele de interfatare, cat si de transmisia si
regimurile tranzitorii ale informatiilor pe magistrala sistemului necesita, adesea,
introducerea unei stari de asteptare (wait state), mai ales pentru microprocesoarele foarte
rapide, atunci cand se adreseaza memoriei care nu se afla pe aceeasi placa.
memoria cache pe aceeasi placa permite obtinerea de timpi de acces la
sistemul de memorie apropiati de cei oferiti de memoria cache de mare viteza, dar la un
pret apropiat de cel al memoriei mai mari si mai lente (memorie primara).
In sistemele multiprocesor apare un motiv suplimentar de introducere a memoriei
cache. In acest sistem, concurenta intre diferitele CPU pentru accesul la memorie
conduce la intarzieri care au ca efect cresterea timpului mediu de acces la memorie. Memoria cache reprezinta un tampon intre memoria principala si CPU.
Memoria principala sau operativa pastreaza programele si datele aferente in curs
de executie. Ea poate fi adresatain mod aleatoriu de un program utilizator.Are o
capacitate medie-mare si un timp de acces mediu. Este un tampon intrememoria virtuala
si CPU.
Memoria virtualaeste un concept arhitectural prin care memoria operativa este
extinsa peste spatiul de adresare al memoriei externe (hard disk, banda magnetica). Prin
tehnicile de implementare, numite segmentare si paginare se urmaresc doua aspecte
esentiale:
cresterea resurselor de memorare disponibile pentru programele utilizator;
protejarea zonelor de memorie alocate modulelor de program.
Memoria virtualaeste utilain cazul sistemelor de operare multitasking simultiuser
(Windows, Unix).
In general, tehnicile de implementare a MC si a MV sunt transparente
pentruprogramele utilizator.Aparent, programele de aplicatie lucreaza numai cu
memoriaprincipala.Transferul de informatii intre diferitele nivele de memorie se
realizeaza in mod automat, fie de catre componente hardware specializate (unitatea de
gestiunea memoriei, MMU), fie de catre sistemul de operare.Procesoarele recente ofera suport hardware pentru implementarea memoriei cache si a memoriei virtuale.
Memoria de masa
Informatia care nu este imediat necesara CPU (programe care nu sint gata de
rulare sau subspatii de adresare care nu sint necesare in faza curenta) este memorata in
dispozitive cu mediu magnetic de stocare, care ofera un mare volum de memorare la
costuri unitare mici, dar cu timpi de acces cu cel putin trei ordine de marime mai mari
decit cei ai memoriei primare.
3. GESTIUNEA MEMORIEI
Subsistemul de gestiune a memoriei din cadrul unui sistem de operare este folosit
de toate celelaltesubsisteme: scheduling, I/O, filesystem, gestiunea proceselor,
networking. Memoria este o resursa importantai sunt necesari algoritmi eficieni de
utilizare i gestiune a acesteia.
Rolul subsistemului de gestiune a memoriei este de a ine evidena zonelor de
memorie fizica ocupate saulibere, de a oferi proceselor sau celorlalte subsisteme acces la
memorie i de a mapa paginile de memorievirtuala ale unui proces (pages) peste paginile
fizice (frames).
Nucleul sistemului de operare ofera un set de interfee (apeluri de sistem) care
permit alocarea/dezalocarea dememorie, maparea unor regiuni de memorie virtuala peste
fiiere, partajarea zonelor de memorie.
Din pacate, nivelul limitat de inelegere a acestor interfee i a aciunilor ce se petrec
in spate conduc la o serie deprobleme foarte des intalnite in aplicaiile software: memory
leak-uri, accese invalide, suprascrieri, bufferoverflow, corupere de zone de memorie.
Este, in consecina, fundamentala cunoaterea contextului in care acioneaza
subsistemul de gestiune a memorieii inelegerea interfeei pusa la dispoziie de sistemul de
operare programatorului.
3.1 Gestiunea memoriei interne
Tehnica de gestionare a informatiilor din memoria interna
Sistemele de calcul includ diverse dispozitive de memorare organizate in final pe
doua nivele:
· memoria interna
· memoria externa.
Pentru a fi executate, programele trebuiesc incarcate in memoria interna a
sistemului de calcul, in zone contigue de memorie; aici, ele sunt parcurse secvential si
executate, instructiune cu instructiune. Tot in memoria interna trebuiesc aduse si datele
asupra carora se fac prelucrari, pentru ca aceasta este memoria pe care CPU o poate
accesa direct si care constituie memoria sa de lucru. Lucrul cu memoria interna
conditioneaza, deci, executarea programelor intr-un sistem de calcul. In acelasi timp,
existenta in memoria interna a informatiilor (programe si date) este conditionata de
transferul acestora cu memoria externa, care constituie suportul permanent de memorare
a lor.
In stabilirea modalitatilor de folosire a memoriei interne trebuie plecat de la
urmatoarele premize:
in timpul executiei programelor exista un permanent schimb de date intre
memoria internasi memoria externa, memoria interna reprezentand memoria de lucru iar
memoria externa reprezentand memoria de stocare;
la un moment dat, in memoria interna, sunt incarcate mai multe programe,
pentru executie (procese generate de programe utilizator sau de programe ale sistemului
de operare);
zonele de memorie alocate fiecarui proces trebuiesc protejate de accesul
celorlalte procese la ele (de exemplu, programele sistemului de operare trebuiesc
protejate de accese nepermise ale programelor utilizator);
pe durata executiei unui program, necesarul de memorie interna, pentru
acest program, este variabil (de exemplu, in cazul programelor segmentate);
spatiul memoriei interne este limitat si este de dorit ca acest lucru sa
limiteze cat mai putin dimensiunea programelor care pot fi executate in sistemul de calcul
sau numarul programelor executate concurent, acolo unde este cazul.
Gestiunea memoriei are rolul de a decide cum trebuie organizata informatia pe
cele doua nivele si cand trebuie transferata informatia intre acestea; tehnicile de gestiune
a lucrarilor (multiprogramare, multitasking, time-sharing,etc) implica existenta unor
metode eficiente pentru gestiunea memoriei: tehnici de alocare dinamicasi memoria
virtuala.
Gestionarea memoriei trebuie sa asigure urmatoarele functii:
organizarea informatiilor in memoria interna (gestionarea informatiilor);
evidenta ocuparii memoriei interne;
organizarea schimbului de informatii intre memoria internasi memoria
externa (gestionarea schimbului de informatii);
asigurarea protectiei informatiilor memorate in memoria interna (protectia
memoriei).
Rezultatul activitatii de gestionare a memoriei trebuie sa fie:
asigurarea unei viteze de executie sporite a programelor, in conditii de
protectie intre programe concurente, in timpul executarii lor;
limitarea restrictiilor legate de dimensiunea programelor care pot fi
executate in sistem sau de numarul programelor care pot fi executate concurent.
Problemele privind gestiunea memoriei sunt rezolvate prin combinarea
elementelor hard ale sistemului de calcul cu componentele soft ale sistemului de operare.
Obiectivul activitatii de gestiune a memoriei este de a furniza o viteza de
executie sporitaa programelor, prin mentinerea in memoria interna a acelor parti din
programe care sunt referite cu o frecventa mare de catre CPU (de regula, programe
independente intre ele); deoarece in memoria interna exista simultan mai multe programe
independente intre ele, pentru a utiliza eficient CPU apar urmatoarele aspecte:
- introducerea in memoria interna a programului ce urmeaza a fi executat necesita
un spatiu de memorie determinat de dimensiunea sa, de spatiul liber din memoria
interna in acel moment si de modul de ocupare al memoriei interne de catre alte
programe;
- pentru zonele de memorie alocate diferitelor programe, trebuie sa se asigure
protectia acestora fata de anumite interferente si adresari cu alte programe.
Executia unui program este conditionata de incarcarea acestuia in memoria
interna, intr-o zona contigua de memorie, adica o zona din memoria interna formata din
locatii de memorie succesive. Fiecare entitate din cadrul unui program (instructiune sau
data care se prelucreaza) se caracterizeaza prin doua adrese in memoria interna:
adresa din memoria interna la care este memoratain timpul executiei
programului, numita adresa fizica; aceasta adresa este caracteristica procesului generat
pentru o anumita executie a programului
adresa determinata ca distanta de la adresa de inceput a programului pana la
adresa entitatii respective, numita adresa relocabila sau adresa relativa.
Pentru executii diferite ale aceluiasi program, adresa relativa este intotdeauna
aceeasi, in timp ce adresa fizica se modifica, de obicei, de la o executie la alta, in functie
de adresa de incarcare a programului in memorie; adresa de incarcare in memorie a unui
program se numeste adresa de bazasi se memoreazain registrul de baza al programului.
Adresa relocabila are proprietatea ca, prin adunare la adresa de baza, determina adresa
fizica a entitatii, in cadrul procesului respectiv.
Se numesc programe relocabile programele care folosesc adrese relocabile;
aceste adrese se genereazain procesul de translatare a programului si in etapa de editare a
legaturilor pentru program. Programele care folosesc numai adrese fixe de memorie
(adresele fizice ale entitatilor lor) se numesc programe nerelocabile; aceste programe
trebuiesc incarcate intotdeauna la aceeasi adresa de memorie, pentru a fi executate.
Translatarea adreselor logice in adrese fizice se realizeaza printr-o functie de
translatare care precede executia instructiunii respective.
Executia unui program este conditionata de incarcarea acestuia in memoria
interna, intr-o zona contigua de memorie, adica o zona din memoria interna formata din
locatii de memorie succesive. Fiecare entitate din cadrul unui program (instructiune sau
data care se prelucreaza) se caracterizeaza prin doua adrese in memoria interna:
executiei (adresa din memoria interna la care este memoratain timpul executiei
programului, numita adresa fizica; aceasta adresa este caracteristica procesului generat
pentru o anumita executie a programului)(numite si adrese fizice) in etapele scrierii si
translatarii programelor a caror adrese de memorie, sunt simbolice (adresa determinata ca
distanta de la adresa de inceput a programului pana la adresa entitatii respective, numita
adresa relocabila sau adresa relativa.)(numite adrese logice). Translatarea adreselor
logice in adrese fizice se realizeaza printr-o functie de translatare care precede executia
instructiunii respective.
Activitatea de gestiune a memoriei are la baza trei algoritmi (fig. De mai jos):
1) algoritmul de transfer care determina cand un bloc trebuie transferat din
memoria externa in memoria interna - inaintea executiei sau in timpul executiei;
2) algoritmul de plasare care determina ce zona nealocata din memoria interna
este folositapentru plasarea blocului incarcat din memoria externa;
3) algoritmul de reamplasare care determina care blocuri si la ce moment trebuie
reincarcate in memoria interna.
Fig. Activitatea de gestiune a memoriei
Pentru executii diferite ale aceluiasi program, adresa relativa este intotdeauna
aceeasi, in timp ce adresa fizica se modifica, de obicei, de la o executie la alta, in functie
de adresa de incarcare a programului in memorie; adresa de incarcare in memorie a unui
program se numeste adresa de bazasi se memoreazain registrul de baza al programului.
Adresa relocabila are proprietatea ca, prin adunare la adresa de baza, determina adresa
fizica a entitatii, in cadrul procesului respectiv.
Organizarea memoriei interne se refera la modul de impartire a memoriei interne
in zone contigui numite partitii, in scopul alocarii lor proceselor generate in sistem.
3.2 Gestiunea memoriei externe Gestionarea datelor si a memoriei externe
Datele constituie una dintre cele mai importante resurse ale unui sistem de calcul,
in primul rand pentru ca activitatea de stocare, prelucrare si transfer de date este
activitatea care justifica existenta sistemelor de calcul, in al doilea rand pentru ca, de cele
mai multe ori, datele gestionate de o aplicatie sunt de neinlocuit, in cazul pierderii lor.
Activitatea de gestionare a datelor sub controlul sistemului de operare constain
organizarea datelor pe suportii de memorie externain scopul stocarii lor si pentru a
permite regasirea lor, in vederea realizarii schimbului de date cu celelalte componente ale
sistemului de calcul.
Atat stocarea cat si accesul utilizatorului la date trebuie sa se facain mod unitar,
indiferent de suportul de memorie externa folosit; in plus, sistemul de operare trebuie sa
faciliteze accesul utilizatorului la date, actionand ca un element de interfataintre utilizator
si echipamentele care realizeaza stocarea datelor.
Fisierul reprezinta unitatea logica de organizare a datelor pe suportul de memorie
externa, in scopul realizarii operatiei de stocare a datelor si de manevrare a lor intre
diferite dispozitive de memorie externa sau dispozitive de intrare/iesire.
Componenta sistemului de operare care asigura gestiunea datelor pe suportii de
memorie externa se numeste sistemul de gestiune a fisierelor (SGF).
Sistemul de operare realizeaza o abstractizare a proprietatilor fizice ale diferitelor
echipamente periferice: dispozitive de memorie externa, pentru stocarea datelor, sau
echipamente de intrare/iesire, pentru realizarea schimbului de date intre sistemul de
calcul si utilizatori. In acest scop, sistemul de operare defineste unitati logice,
corespunzatoare acestor echipamente, unitati logice numite device-uri. Pentru fiecare tip
de device, sistemul de operare furnizeaza cate un program de interfata numit driver.
Schimbul de date gestionat de SGF se realizeaza la nivel de fisier, prin cooperarea
rutinelor SGF cu programele driver corespunzatoare echipamentelor periferice implicate.
Functiile indeplinite de SGF pentru gestionarea datelor stocate pe suportii de
memorie externa sunt:
functia de evidenta a fisierelor, care trebuie sa ofere date despre fisiere si
despre modul de organizare a fisierelor pe suport cat si despre drepturile de acces ale
utilizatorilor la fisiere;
functia de alocare a memoriei externe, pentru stocarea fisierelor; pentru
realizarea acestei functii, sistemul de operare trebuie sa realizeze si o evidenta a ocuparii
dispozitivelor de memorie externa;
functia de dezalocare a memoriei externe, prin eliberarea memoriei externe
ocupate;
functia de acces la date, care trebuie sa faciliteze accesul utilizatorului la
date, prin localizarea inregistrarii dorite si accesarea ei, conform drepturilor de acces.
Utilizand conceptul de fisier, se poate spune ca SGF este acea componenta a
sistemului de operare care implementeaza operatiile de creare, intretinere si exploatare a
fisierelor.
Tinand cont de functiile pe care trebuie sa le indeplineascain sistemul de calcul,
SGF trebuie sa satisfaca urmatoarele conditii:
sa asigure un mecanism de lucru cu fisierele cat mai accesibil pentru
utilizator;
sa permita o utilizare cat mai eficientaa dispozitivelor de memorie externa;
sa asigure o independenta maximaa programelor fata de particularitatile
hardware ale sistemului de calcul;
sa permita accesul concurent la fisiere;
sa asigure securitatea si integritatea datelor memorate in fisiere.
Evidenta fisierelor
Functia SGF de evidenta a fisierelor pe suportii de memorie externa trebuie sa
rezolve urmatoarele probleme:
identificarea fisierului si memorarea caracteristicilor generale ale sale;
organizarea unui sistem de cataloage pentru inregistrarea tuturor fisierelor
de pe un dispozitiv de memorie externa. Dintre toate dispozitivele de memorie externa, discurile magnetice necesita cea
mai complexa evidenta a fisierelor pe care le memoreaza, pentru ca sunt dispozitive care
permit stocarea simultana a mai multor fisiere (dispozitive multifisier) si sunt direct
adresabile, deci modul de organizare a evidentei fisierelor pe suport trebuie sa permita
accesul direct la fisiere.
Fiecare volum de disc contine cate o tabela cu informatii despre fisierele
memorate in volumul respectiv, tabela numita catalog de fisiere sau director. Accesul la
fisiere se face pe baza datelor din aceasta tabela; fiecare intrare in tabela director contine
cate un descriptor de fisier, ce cuprinde date despre fisier, si anume:
identificatorul de fisier, format dintr-o pereche de valori, de forma
(Nume,Indicativ), unde Nume este numele simbolic al fisierului, recunoscut de utilizator,
iar Indicativ este un numar prin care fisierul este identificat intern, de catre SGF;
informatii de adresa care permit localizarea fisierului in disc; natura acestor
informatii difera, in functie de modul de alocare a discului folosit pentru generarea
fisierului;
informatii pentru controlul accesului la fisier, prin care sistemul de operare
realizeaza functia de protectie a datelor:
atributele de fisier (de exemplu: fisier read-only, fisier sistem, fisier ascuns
aplicatiilor obisnuite)
utilizatorii si drepturile de acces la fisier pe care le au (de exemplu: W
acces in scriere, R acces in citire, A acces pentru modificare, D acces pentru stergere)
drepturi de partajare a fisierului, de exemplu in cadrul unei retele de
calculatoare;
informatii despre date calendaristice, de exemplu: data cand a fost creat
fisierul, data ultimei actualizari, data ultimei consultari;
alte informatii despre fisier, de exemplu: modul de organizare, dupa modul
de alocare a suportului (contigua, inlantuita, indexata), tipul de fisier, dupa formatul
articolului (cu format fix, variabil, nedeterminat), dupa modul de codificare a datelor
(fisier binar, fisier text), dupa durata stocarii pe suport (permanent, temporar, la termen),
numarul de accese la fisier, etc.
Modul de organizare a sistemului de fisiere in directori poate fi:
cu un singur nivel, definind un director unic pentru fiecare volum de disc;
acest director are dimensiune fixa, deci numarul de intrari in director este fix, adica
numarul maxim de fisiere care pot fi memorate in volumul de disc este limitat de
aceastavaloare maxima. Pentru o astfel de organizare a sistemului de fisiere, pe un volum
de disc poate fi un singur fisier cu un anumit nume (identificator);
cu doua niveluri, intre care exista o relatie de subordonare: · pe primul nivel se defineste un director principal MFD (Master File Directory),
avand cate o intrare pentru fiecare utilizator; in felul acesta se asigura protectia datelor
intre utilizatori, pentru ca drepturile de acces ale unui utilizator se pot limita la fisierele
din propriul sau director;
· pe al doilea nivel sunt definiti directorii utilizatorilor, UFD (User File
Directory), care contin cate o intrare pentru fiecare fisier al utilizatorului respectiv. Pentru
o astfel de organizare, pot exista pe un volum de disc mai multe fisiere cu acelasi nume,
cu conditia sa apartina la UFD-uri diferite; cu structura de arbore, care extinde modul de organizare de mai sus la mai
multe niveluri; fiecare volum contine un director principal, numit radacina; intrarile unui
director contine descriptori pentru toate fisierele pe care le include; un director este tot un
fisier, care difera de fisierele utilizator numai prin continut; rezulta ca un director poate
contine oricati directori sau oricate fisiere, cu conditia ca orice fisier sa se gaseascaintr-un
singur director;
cu structura de graf aciclic, asemanatoare organizarii in arbore de directori,
dar cu deosebirea ca un fisier poate sa apartinala mai multi directori.
Evidenta ocuparii volumului de disc.
Pentru a realiza alocarea spatiului din disc, sistemul de operare trebuie sa asigure o
evidenta a modului in care este ocupat fiecare volum si a spatiului liber din disc. In acest
scop, volumul este impartit in unitati de alocare de lungime fixa, numite blocuri si
numerotate secvential; exista mai multe modalitati de realizare a evidentei blocurilor
libere si a celor ocupate:
cu ajutorul tabelei de ocupare a volumului (TOV), care are atatea pozitii
cate blocuri are volumul; in fiecare pozitie se memoreaza cate un indicator, care este setat
pe 0 daca blocul nu este ocupat si pe o valoare diferita de 0 la ocuparea blocului;
cu ajutorul unei liste inlantuite a blocurilor libere; in directorul volumului
se memoreaza un pointer la primul bloc liber de pe volum; fiecare bloc liber contine un
pointer la urmatorul bloc liber; ultimul bloc liber contine un indicator de sfarsit de lista;
alocarea unui bloc se face cu scoaterea lui din lista (de obicei de la unul din capetele
listei); eliberarea unui bloc se face cu inserarea blocului in lista; dezavantajul este ca
pentru consultarea listei, de exemplu pentru a determina numarul blocurilor libere din
disc, trebuie incarcate in memoria interna atatea blocuri cate se consulta;
metoda mai eficienta este evidenta printr-o listainlantuitasi indexata a
ocuparii volumului; in primul bloc liber din volum se memoreaza cate adrese de blocuri
libere incap; acest bloc se numeste bloc de index; daca numarul blocurilor libere
depaseste capacitatea blocului de index, pe ultima pozitie din blocul de index se
memoreaza adresa unui nou bloc de index, samd; in directorul volumului se
memoreazaun pointer catre primul bloc de index; alocarea de blocuri libere ca si
inserarea unor blocuri eliberate in blocurile de index se realizeaza la nivelul ultimului
bloc de index.
Alocarea spatiului pe disc
In functie de modalitatea de alocare a discului se determina modul de acces la
fisier si informatiile care se memoreazain descriptorul de fisier, pentru a permite
accesarea fisierului. Exista mai multe moduri de alocare a discului pentru generarea unui
fisier:
alocarea este contigua atunci cand fisierul ocupa un set de adrese
consecutive in disc; pentru a face posibil accesul la fisier, in descriptorul de fisier
trebuiesc precizate: adresa de inceput a fisierului si lungimea fisierului; in cazul utilizarii
alocarii contigue poate sa apara, in timp, o fragmentare a discului si necesitatea
compactarii datelor din volum;
alocarea inlantuita se realizeaza cand blocurile fisierului alcatuiesc o
listainlantuita; acest mod de alocare permite numai accesul secvential la fisier; in
descriptorul de fisier se memoreaza adresa primului bloc al fisierului, pentru a permite
citirea fisierului si adresa ultimului bloc, pentru a permite extinderea fisierului;
alocarea indexata foloseste un bloc suplimentar, numit bloc de index, care
se genereaza odata cu fisierul; in blocul de index se memoreaza, in ordinea alocarii lor,
adresele blocurilor fisierului; pentru fisiere mari, blocurile de index se pot inlantui;
aceasta alocare permite accesul direct la un bloc de date din fisier; in descriptorul de
fisier se memoreaza adresa primului bloc de index si numarul de blocuri alocate
fisierului.
4. SPATIUL DE ADRESA AL
UNUI PROCES
Spațiul de adrese al unui proces, sau, mai bine spus, spațiul virtual de adresa al
unui proces reprezinta zona de memorie virtuala utilizabila de un proces. Fiecare proces
are un spațiu de adresa propriu. Chiar in situațiile in care doua procese partajeaza o zona
de memorie, spațiul virtual este distinct, dar se mapeaza peste aceeasi zona de memorie
fizica.
In figura alaturataeste prezentat un spațiu de adresa tipic pentru un proces. In
sistemele de operare moderne, in spațiul virtual al fiecarui proces se mapeaza memoria
nucleului, aceasta poate fi mapata fie la inceput, fie la sfarsitul spațiului de adresa.In
continuare, ne vom referi numai la spațiul de adresa din user-space pentru un proces.
Cele 4 zone importante din spațiul de adresa al unui proces sunt zona de date, zona
de cod, stiva si heap-ul. Dupa cum se observasi din figura, stiva si heap-ul sunt zonele
care pot creste. De fapt, aceste doua zone sunt dinamice si au sens doar in contextul unui
proces.De partea cealalta, informațiile din zona de date si din zona de cod sunt descrise in
executabil.
Zona de cod Segmentul de cod (denumit si text segment) reprezinta instrucțiunile in limbaj
masina ale programului. Registrul de tip instruction pointer (IP) va referi adrese din zona
de cod. Se citeste instrucțiunea indicata de catre IP, se decodificasi se interpreteaza, dupa
care se incrementeaza contorul programului si se trece la urmatoarea instrucțiune.
Zona de cod este, de obicei, o zona read-only pentru ca procesul sa nu poata modifica
propriile instrucțiuni prin folosirea gresita a unui pointer. Zona de cod este partajataintre
toate procesele care ruleaza acelasi program. Astfel, o singura copie a codului este
mapatain spațiul de adresa virtual al tuturor proceselor.
Zone de date Zonele de date conțin variabilele globale definite intr-un program si variabilele de
tipul read-only.In funcție de tipul de date exista mai multe subtipuri de zone de date.
.data
Zona .data conține variabilele globale si statice inițializate la valori nenule ale unui
program. De exemplu:
staticint a =3;
char b ='a';
.bss
Zona .bss conține variabilele globale si statice neinițializate ale unui
program.Inainte de execuția codului, acest segment este inițializat cu 0. De exemplu:
staticint a;
char b;
In general aceste variabile nu vor fi prealocate in executabil, ci in momentul
crearii procesului. Alocarea zonei .bss se face peste pagini fizice zero (zeroed frames).
.rodata
Zona .rodata conține informație care poate fi doar citita, nu si modificata. Aici sunt
stocate constantele:
constint a;
constchar*ptr;
si literalii:
"Hello, World!"
"En Taro Adun!"
Stiva Stiva este o regiune dinamicain cadrul unui proces, fiind gestionata automat de
compilator.
Stiva este folosita pentru a stoca “stack frame-uri”. Pentru fiecare apel de funcție
se va crea un nou “stack frame”.
Un “stack frame” conține:
variabile locale
argumentele funcției
adresa de retur
Pe marea majoritate a arhitecturilor moderne stiva creste in jossi heap-ul creste in
sus. Stiva creste la fiecare apel de funcție si scade la fiecare revenire din funcție.
In figura de mai jos este prezentata o vedere conceptuala asupra stivei in
momentul apelului unei funcții.
Heap-ul Heap-ul este zona de memorie dedicata alocarii dinamice a memoriei. Heap-ul este
folosit pentru alocarea de regiuni de memorie a caror dimensiune este determinata la
runtime.
La fel ca si stiva, heap-ul este o regiune dinamica care isi modifica dimensiunea.
Spre deosebire de stiva, insa, heap-ul nu este gestionat de compilator. Este de datoria
programatorului sastie cata memorie trebuie sa aloce si sa rețina cat a alocat si cand
trebuie sa dealoce. Problemele frecvente in majoritatea programelor țin de pierderea
referințelor la zonele alocate (memory leaks) sau referirea de zone nealocate sau
insuficient alocate (accese nevalide).
In limbaje precum Java, Lisp etc. unde nu exista “pointer freedom”, eliberarea
spațiului alocat se face automat prin intermediul unui garbage collector. Pe aceste sisteme
se previne problema pierderii referințelor, dar inca ramane activa problema referirii
zonelor nealocate.
5. MECANISMELE DE
GESTIONARE A MEMORIEI LA
WINDOWS
Sub sistemul de operare DOS, fiecare program avea incorporat in fisierul
executabil coduri pentru functiile de baza. Acest principiu functiona perfect, deoarece sub
DOS intotdeauna rula un singur program care stapinea in exclusivitate memoria.
Sub Windows mai multe programe trebuie sa-si partajeze memoria disponibila,
deoarece sistemul este cunoscut ca fiind un mare consumator de memorie RAM. Daca
proiectantii de aplicatii ar fi incorporat fiecarui program codurile de baza pentru
administrarea memoriei, a ferestrelor, afisarea caracterilor, imprimarea etc. memoria de
lucru nu ar fi suficienta pentru incarcarea aplicatiilor.
Sub Windows exista patru principii de gestionare a memoriei interne, in sensul
economisirii ei:
- principiul DLL
- principiul segmentelor de cod retrase
- principiul replicarii instantelor active
- principiul memorarii virtuale
PRINCIPIUL DLL Principiul DLL reprezinta o facilitate de gestionare a memoriei prin care se pot
introduce toate functiile de baza, care sunt necesare tuturor programelor in module care
contin seturi de functii utilizate in comun de catre aplicatii.
Principiul DLL consta in faptul ca un program care se afla in executie "stie"
dinainte ce functie trebuie sa foloseasca pentru a executa o anumita prelucrare si
comunica astfel inca de la lansare ce DLL trebuie sa utilizeze. Daca Windows gaseste
DLL-ul cautat, il incarca si-l executa, dupa care, la terminare reda controlul programului
apelant.
Avantajul incontestabil pe care il dau fisierele DLL este economiserea memoriei
necesare aplicatiilor care prin punerea in comun a functiilor de baza, ocupa mai putina
memorie. Un fisier DLL se introduce o singura data in memorie indiferent cite programe
ii acceseaza functiile. Toate facilitatile noi proprii aplicatiilor (OLE, multimedia) sunt
introduse prin fisiere tip biblioteca de functii: DLL.
PRINCIPIUL SEGMENTELOR DE COD RETRASE Spatiul pe care il ocupa un program in memoria interna se imparte in doua
domenii: segmente de cod si segmente de date.
Segmentele de cod ale unui program sau DLL contin codurile executabile ale
aplicatiei - adica instructiunile care realizeaza functiile proprii aferente
programului.Aceste instructiuni nu se modifica in timpul executiei programului.
Segmentele de date contin informatii ce se modifica permanent in timpul executiei
aplicatiei curente. Aceste informatii sunt valori luate pentru scopuri interne sau date
introduse de utilizator. Continutul unui segment de date se poate modifica de la o secunda
la alta, de la o executie la alta - in timp ce continutul segmentului de cod ramine acelasi.
Windows analizeaza memoria disponibila si daca aceasta este insuficienta, va
elimina din memoria RAM segmentele de cod cele mai putin utilizate. Daca un program
are nevoie de un segment pe care windows l-a indepartat deja din memorie, modulul de
administrare a memoriei il va incarca automat in RAM de pe hard disc, astfel incit
functionarea aplicatiei sa nu fie afectata. Acest mecanism de incarcare dinamica
functioneaza numai cu segmente de cod, pentru ca aceastea nu isi schimba continutul in
cursul executiei.
REPLICAREA INSTANTELOR ACTIVE Sub Windows, mai multe aplicatii identice se pot executa de mai multe ori,
aparent simultan. Copiile aflate simultan in executie se numesc instante active.Fiecare
instanta a unui program ocupa memorie interna, atit pentru segmentele de cod, cit si
pentru segmentele de date.Segmentele de cod ale aceleiasi instante active sunt identice.
Mecanismul replicarii instantelor active consta in urmatorul principiu: prima
instanta a programului ocupa spatiu, atit pentru coduri, cit si pentru date, iar oricare alta
instanta aferenta aceluiasi program relansat va utiliza segmentele de cod ale primei
instante si va avea nevoie de memorie pentru segmentele de date. De exemplu aplicatia
WordPad ocupa in total 85 KB la prima lansare (40 KB memorie pentru coduri si 45 KB
pentru date), iar la a doua lansare a instantei ocupa doar 45 KB, spatiu doar pentru date.
MECANISMUL MEMORIEI VIRTUALE Managerul de memorie din Windows poate pune la dispozitia programelor mai
multa memorie interna decit exista fizic pe calculator. Sistemul reuseste acest lucru
transferind blocuri de informatii din memorie pe hard disc, aducindu-le eventual inapoi in
memorie.Astfel, sistemul simuleaza memoria RAM cu memoria externa de pe hard disc,
procesul fiind cunoscut sub forma memoriei virtuale.Segmentele transferate pe disc sunt
cele mai putin utilizate.
In cazul mecanismului SWAP al memoriei virtuale, nu se mai face diferenta intre
segmentele de cod si de date, prin transfer neexistind nici o pierdere de informatii.
Subliniez faptul ca aceste fisiere se pot crea nu numai pe discul local ci si pe o unitate de
disc in retea sau pe un RAM-DRIVE. In primul caz are loc o incetinire a sistemului
deoarece, la fiecare apelare a mecanismului SWAP, se apeleaza reteaua, iar in al doilea
caz, dezavantajul care apare este ca fiecare byte ocupat de RAM-DRIVE ii va lipsi
memoriei de lucru.
In ceea ce priveste dimensionarea acestor fisiere SWAP, se impune sa se aleaga o
cale de mijloc deoarece, daca spatiul alocat acestora este prea mare, atunci sistemul este
frinat, in caz contrar nu mai functioneaza. In general, se afirma ca fisierul SWAP ar
trebui sa fie mai mare de doua ori decit memoria de lucru fizica. Daca exista o modalitate
de lucru suficienta si se simte o lipsa acuta de spatiu pe discul hard, atunci se poate
renunta la tot mecanismul SWAP.
Exista cel putin doua modalitati de abordare a acestui mecanism si anume in mod
standard si in mod extins. In primul caz Windows nu poate folosi mecanismul SWAP
pentru propriile aplicatii, fiind disponibil exclusiv pentru programele DOS; datele se pot
scrie in fisiere temporare doar daca se porneste un program DOS. In al doilea caz,
mecanismul SWAP da rezultate mult mai bune deoarece se pot scrie segmentele de
memorie si cind nu e vorba de o aplicatie MS-DOS. Aceste segmente se salveaza pe hard
disc atunci cind unei aplicatii Windows nu-I mai ajunge memoria disponibila. In acest
fel, administrarea memoriei este preluata de Windows care va colabora cu unitatea
centrala.
Un fisier SWAP temporar poate pune la dispozitia sistemului Windows o memorie
marita considerabil. Fisierele SWAP permanente spre deosebire de cele temporare nu se
creeaza la pornirea sistemului Windows si nu se sterg la parasirea acestuia, ci au un loc
rezervat chiar chiar si atunci cind nu se ruleaza Windows. In primul caz viteza este destul
de mica deoarece in anumite conditii Windows-ul nu poate scrie intregul fisier pe hard
disc, iar in al doilea caz, se inregistreaza un insemnat cistig de viteza, dar se impune ca
fisierul SWAP sa ocupe un loc nefragmentat pe discul local. In cazul fisierului permanent
se poate activa si accesul la discul hard pe 32 de biti, ceea ce determina un transfer mai
mare de date.
6. ALOCAREA /
DEZALOCAREA MEMORIEI
Alocarea memoriei este realizata static de compilator sau dinamic, in timpul
execuției. Alocarea statica e realizatain segmentele de date pentru variabilele locale sau
pentru literali.
In timpul execuției, variabilele se aloca pe stiva sau in heap. Alocarea pe stiva se
realizeaza automat de compilator pentru variabilele locale unei funcții (mai putin
variabilele locale prefixate de identificatorulstatic).
Alocarea dinamica se realizeazain heap. Alocarea dinamica are loc atunci cand nu
se stie, in momentul compilarii, cata memorie va fi necesara pentru o variabila, o
structura, un vector. Daca se stie din momentul compilarii, cat spațiu va ocupa o
variabila, se recomanda alocarea ei statica, pentru a preveni erorile frecvent aparute in
contextul alocarii dinamice.
Pentru a fragmenta cat mai puțin spațiul de adrese al procesului, ca urmare
a alocarilor si dezalocarilor unor zone de dimensiuni variate, alocatorul de memorie va
organiza segmentul de date alocate dinamic sub forma de heap, de unde si numele
segmentului.
Dezalocarea memoriei inseamna eliberarea zonei de memorie (este
marcata ca fiind libera) alocate dinamic anterior.
Daca se omite dezalocarea unei zone de memorie, aceasta va ramane alocata pe
intreaga durata de rulare a procesului. Ori de cate ori nu mai este nevoie de o zona de
memorie, aceasta trebuie dezalocata pentru eficiența utilizarii spațiului de memorie.
Nu trebuie neaparat realizata dezalocarea diverselor zone inainte de un
apel exit sau inainte de incheierea programului pentru ca acestea sunt automat eliberate
de sistemul de operare.
Atenție! Pot aparea probleme si daca se incearca dezalocarea aceleiasi regiuni de
memorie de doua sau mai multe ori si se corup datele interne de management al zonelor
alocate dintr-un heap.
6.1 Alocarea Memoriei in Windows
In Windows, un proces poate sa-si creeze mai multe obiecte Heap pe
langa Heap-ul cu care este creat procesul. Acest lucru este foarte util in momentul in care
o aplicație alocasi dezaloca foarte multe zone de memorie cu cateva dimensiuni fixe.
Aplicația poate sa-si creeze cate un Heap pentru fiecare dimensiune si, in cadrul
fiecarui Heap, sa aloce zone de aceeasi dimensiune reducand astfel la maxim
fragmentarea heapului.
Pentru crearea, respectiv distrugerea, unui Heap se vor folosi
funcțiile HeapCreate si HeapDestroy:
HANDLE HeapCreate(
DWORD flOptions,
SIZE_T dwInitialSize,
SIZE_T dwMaximumSize
);
BOOL HeapDestroy(
HANDLE hHeap
);
Pentru a obține un descriptor al heapului cu care a fost creat procesul (in cazul in
care nu dorim crearea altor heapuri) se va apela funcția GetProcessHeap . Pentru a obține
descriptorii tuturor heapurilor procesului se va apelaGetProcessHeaps.
Exista, de asemenea funcții care enumera toate blocurile alocate intr-un heap,
valideaza unul sau toate blocurile alocate intr-un heap sau intorc dimensiunea unui bloc
pe baza descriptorului de heap si a adresei blocului:HeapWalk, HeapValidate, HeapSize.
Pentru alocarea, dezalocarea, redimensionarea unui bloc de memorie din Heap,
Windows pune la dispoziția programatorului funcțiile HeapAlloc, HeapFree,
respectiv HeapReAlloc, cu signaturile de mai jos:
LPVOID HeapAlloc(
HANDLE hHeap,
DWORD dwFlags,
SIZE_T dwBytes
);
BOOL HeapFree(
HANDLE hHeap,
DWORD dwFlags,
LPVOID lpMem
);
LPVOID HeapReAlloc(
HANDLE hHeap,
DWORD dwFlags,
LPVOID lpMem,
SIZE_T dwBytes
);
In continuare este prezentat un exemple de folosire a acestor funcții:
#include <windows.h>
#include "utils.h"
/* Example of matrix allocation */
int main(void)
{
HANDLE processHeap;
DWORD **mat;
DWORD i, j, m = 10, n = 10;
processHeap = GetProcessHeap();
DIE (processHeap == NULL, "GetProcessHeap");
mat = HeapAlloc(processHeap, 0, m * sizeof(*mat));
DIE (mat == NULL, "HeapAlloc");
for (i = 0; i < n; i++) {
mat[i] = HeapAlloc(processHeap, 0, n * sizeof(**mat));
if (mat[i] == NULL) {
PrintLastError("HeapAlloc failed");
goto freeMem; /* free previously allocated memory */
}
}
/* do work */
freeMem:
for (j = 0; j < i; j++)
HeapFree(processHeap, 0, mat[j]);
HeapFree(processHeap, 0, mat);
return 0;
}
Pe sistemele Windows se pot folosi si funcțiile bibliotecii standard C pentru
gestiunea memoriei: malloc, realloc,calloc, free, dar apelurile de sistem specifice
Windows ofera funcționalitați suplimentare si nu implica legarea bibliotecii standard C in
executabil.
6.2 Alocarea memoriei in Linux
In Linux,alocarea memoriei pentru procesele utilizator se realizeaza prin
intermediul funcțiilor de biblioteca malloc,calloc si realloc, iar dezalocarea ei prin
intermediul funcției free. Aceste funcții reprezinta apeluri de bibliotecasi rezolva cererile
de alocare si dezalocare de memorie, pe cat posibil, in user space.
void *calloc(size_t nmemb, size_t size);
void *malloc(size_t size);
void *realloc(void *ptr, size_t size);
void free(void *ptr);
Intotdeauna eliberați (free) memoria alocata. Memoria alocata de proces
este eliberata automat la terminarea procesului, insa, de exemplu in cazul unui proces
server care ruleaza foarte mult timp si nu elibereaza memoria alocata acesta va ajunge sa
ocupe toata memoria disponibilain sistem, cauzand astfel consecințe nefaste.
Atenție!
Nu eliberați de doua ori aceeasi zona de memorie intrucat acest lucru va
avea drept urmare coruperea tabelelor ținute de malloc ceea ce va duce din nou la
consecințe nefaste. Intrucat funcția free se intoarce imediat daca primeste ca parametru
un pointer NULL, este recomandat ca dupa un apel free, pointer-ul sa fie resetat
la NULL.
In continuare sunt prezentate cateva exemple de alocare a memoriei:
int n = atoi(argv[1]);
char *str;
/* usually malloc receives the size argument like:
num_elements * size_of_element */
str = malloc((n + 1) * sizeof(char));
if (NULL == str) {
perror("malloc");
exit(EXIT_FAILURE);
}
[...]
free(str);
str = NULL;
/* Creating an array of references to the arguments received by a program */
char **argv_no_exec;
/* allocate space for the array */
argv_no_exec = (char **) malloc((argc - 1) * sizeof(char*));
if (NULL == argv_no_exec) {
perror("malloc");
exit(EXIT_FAILURE);
}
/* set references to the program arguments */
for (i = 1; i < argc; i++)
argv_no_exec[i-1] = argv[i];
[...]
free(argv_no_exec);
argv_no_exec = NULL;
Apelul realloc este folosit pentru modificarea spațiului de memorie alocat cu un
apel malloc sau calloc:
int *p;
p = malloc(n * sizeof(int));
if (NULL == p) {
perror("malloc");
exit(EXIT_FAILURE);
}
[...]
p = realloc(p, (n + extra) * sizeof(int));
[...]
free(p);
p = NULL;
Apelul calloc este folosit pentru alocarea de zone de memoire al caror conținut
este nul (plin de valori de zero). Spre deosebire de malloc, apelul va primi doua
argumente: numarul deelemente si dimensiunea unui element.
Atenție!
Conform standardului C este redundant ( si considerat bad practice ) sa
faceți cast la valoarea intoarsa de malloc.
int *p = (int *)malloc(10 * sizeof(int));
mallocintoarce void * care in C este automat convetit la tipul dorit. Mai mult, daca
se face cast iar headerul stdlib.hnecesar pentru funcția malloc nu este inclus, nu se va
genera eroare! Pe anumite arhitecturi acest caz poate conduce la comportament
nedefinit.Spre deodebire de C, in C++ este nevoie de cast. Mai multe detalii despre
problema aceastaaici
Mai multe informații despre funcțiile de alocare gasiți in manualul bibliotecii
standard C si in pagina de manual man malloc.
list_t *list_v; /* list_t could by any C type ( except void ) */
list_v = calloc(n, sizeof(list_t));
if (NULL == list_v) {
perror("calloc");
exit(EXIT_FAILURE);
}
[...]
free(p);
p = NULL;
6.3 Dezalocarea memoriei
Pentru dezalocarea memoriei, se folosesc funciile free, respectiv HeapFree.
Funciile primesc ca argument un pointer la un spaiu de memorie alocat anterior cu o
funcie de alocare.
Daca se omite dezalocarea unei zone de memorie, aceasta va ramane alocata pe
intreaga durata de rulare a procesului. Ori de cate ori nu mai este nevoie de o zona de
memorie, aceasta trebuie dezalocata pentru eficiena utilizarii spaiului de memorie.
Nu trebuie neaparat realizata dezalocarea diverselor zone inainte de un apel exit
sau ExitProcess sau inainte de incheierea programului pentru ca acestea sunt automat
eliberate de sistemul de operare. Probleme pot aparea i daca se incearca dezalocarea
aceleiai regiuni de memorie de doua sau mai multe ori i se corup listele.
7. Paginarea memoriei Paginarea este procedeul de realizare in memorie a unor blocuri fixe, numite
pagini, care pot fi utilizate in mecanismul interschimbarii proceselor (transferal blocurilor
intre memoria interna si cea externa). Tehnica paginarii este larg folosita si poate fi
independent de gestionarea memoriei. Exista procesoare care creeaza pagini in memoria
fizica, sau, ca in cazul familiei Intel, in memoria virtuala.
Cand un program da o comanda de punere a unei valori in memorie se genereaza
o adresa numita “adresa virtuala” care face parte din spatiul adreselor virtuale. Daca
memoria virtuala nu este disponibila atunci adresa este pusa direct pe bus-ul de memorie
si adresa respectiva din memoria fizica este scrisa sau citita dupa caz. Cand memoria
virtuala este disponibila adresa nu este trimisa automat pe bus-ul de memorie ci este
trimisa la MMU (Unitatea de gestiune a memoriei) care transforma adresa virtuala in
adresa fizica cum ne este aratat in figura urmatoare.
In orice moment avem doar 8 adrese virtuale legate de memoria fizica, restul fiind
marcate ca neavand o adresa fizica. Daca un program acceseaza o astfel de locatie de
memorie care nu are corespondenta in memoria fizica atunci se da un mesaj sistemului de
operare ( numit “page fault”) care ia continutul unei locatii de memorie fizica nefolosita,
o copiaza pe disc si apoi aloca noul spatiu creat adresei virtuale cerute de program. Daca
se acceseaza o valoare ce nu are corespondenta in memoria fizica si nici nu exista pe disc,
atunci inseamna ca acea pagina nu mai exista sau a aparut o eroare si atunci acea intrare
va fi eliminata din memorie.
Paginarea mai detaliata
Avantajele paginarii:
Marimea fixa a paginilor intra correct intr-un sector al unui disc;
Un obiect in memorie nu trebuie sa fie continuu: pagina poate constitui o
noua cuanta de informatie;
Mecanismul paginarii si, implicit intreaga tehnica de a schimba continuu
blocurile fixe de informatie intre memoria interna si cea externa sunt invizibile
utilizatorului.
7.1 Maparea adreselor folosind pagini
In cazul paginarii, implementarea tabelului pentru maparea adreselor este simpla
pentru ca informatia din spatiile de adresare si memorare este divizatain blocuri de
dimensiune fixa. Memoria fizicaesteimpartita logic in blocuri de aceeasi dimensiune (64-
4096 cuvinte fiecare). Termenul paginase refera la blocuri, de aceeasi dimensiune, de
adrese din spatiul de adresare. De exemplu, presupunem un calculator care are 20 de biti
de adresasi foloseste doar 32KB in memoria principala (memorie implementata fizic prin
circuite de memorie); daca o pagina, respectiv un bloc, au dimensiuni egale cu 1 kB,
atunci spatiul de adrese e divizat in 1024 pagini, iar spatiul de memorie e divizat in 32 de
blocuri. Se considera casi programele sunt impartite in pagini. Portiuni din programe sunt
mutate din memoria auxiliarain memoria principalain inregistrari egale cu marimea
paginii. In loc de bloc de memorie e folosit uneori termenul de cadru pagina (“page
frame”).
In cazul maparii prin paginare adresa virtualaeste reprezentata printr-un singur
cuvant de adresaimpartit intr-un camp corespunzator numarului paginii (adresa paginii) si
un camp pentru deplasament. La maparea prin segmentarea un singur cuvant de adresa nu
mai este suficient; dimensiunea variabila a segmentelor conduce la existenta a doua
cuvinte de adresare, in care primul indica numarul (adresa) segmentului, iar cel de-al
doilea deplasamentul in cadrul segmentului.
Intr-un calculator cu 2p cuvinte pe pagina, p biti sunt folositi pentru a specifica o
adresa de linie iar cei mai semnificativi biti ramasi in adresa virtuala specifica numarul de
pagina. Fie de exemplu un system simplu cu o adresa virtuala cu dimensiunea de 16 biti
si pagini cu 4096 cuvinte. Pentru ca o pagina are 212 cuvinte, cei patru biti mai
semnificativi vor specifica una din cele 16 pagini, iar cei 12 biti mai putin semnificativi
indica adresa liniei in cadrul paginii.
Ca urmare maparea trebuie facuta doar de la un numar de pagina la un numar de
bloc din memoria principala, pentru ca adresa liniei e aceeasi pentru ambele spatii.
Organizarea de principiu a tabelului de mapare a memoriei intr-un sistem paginat poate
arata ca in figura 3.
In tabelul paginii de memorie, adresa conduce la numarul paginii, iar continutul
indica numarul blocului unde pagina este stocatain memoria principala. Se observa ca
paginile virtuale 2, 3, 5 si 8 se aflain memoria principala, in blocurile 3, 0, 1 si respectiv
2.Un bit de prezenta adaugat fiecarei locatii a tabelului indica daca pagina respectiva a
fost mapatain memoria principala (i s-a alocat spatiu si a fost transferata din memoria
auxiliarain memoria principala). Valoarea 0 a bitului de prezenta indica ca pagina nu
estein memoria principala. In exemplul dat, cei 4 biti ai adresei virtuale specifica atat
numarul paginii cat si adresa in tabelul paginilor de memorie. Continutul tabelului este
citit in registrul ce indica blocul de memorie. Daca bitul de prezentaeste 1, numarul de
bloc e transferat in registrul ce pastreaza adresa fizica din memoria principala. Daca bitul
de prezentaeste 0 rezulta ca adresa virtuala se refera la un articol ce nu se gaseste in
memoria principala. In acest caz, se genereaza o cerere (in forma unei intreruperi
software, de tip “eroare de pagina2”) catre sistemul de operare (SO) pentru a aduce
pagina ceruta din memoria auxiliarain memoria principala, inainte de reluarea
programului care a accesat adresa din pagina respectiva.
O astfel de organizare in memoria principala a tabelului de translatare esteinsa
ineficienta, caci tabelul are multe locatii goale. Daca presupunem un calculator cu spatiul
de adrese de 4 GB (232), cu pagini de memorie de 32 KB (215), iar spatiul memoriei
fizice este 32 MB (225) rezulta 128 K-pagini virtuale de memorie si 1024 blocuri (1 K-
blocuri). Conform principiului din figura 6.24 tabelul de translatare ar avea 131071 (217
= 128 K) linii si doar 1024 locatii ar fi ocupate (cu bit de prezenta 1), restul fiind goale,
neutilizate. O solutie a acestei probleme o constituie folosirea unei memorii asociative, ca
in figura 4 (tabel asociativ de pagini de memorie) cu numar de locatii egal cu numarul
deblocuri din memoria principala.
In fiecare locatie de memorie se stocheaza numarul paginii virtuale si numarul
corespunzator al blocului de memorie principala alocat.
Adresa logica se compara combinational cu continutul tabelului asociativ, doar
pentru pozitiile binare ce corespund la 1 logic in registrul de mascare, deci in figura 4,
doar pentru campul de adresa al numarului de pagina virtuala. Daca la apelarea unei
pagini virtuale, aceasta nu este mapatain memoria principala, operatia de adresare este o
ratare (miss) si evenimentul este rezolvat printr-o rutina de servire a sistemului de operare
care aduce pagina respectiva din memoria auxiliara. Si acest tabel asociativ de translatare
poate avea dimensiuni mari uneori. De aceea se folosesc tabele asociative de mare viteza
la care numarul liniilor este mai mic decat numarul de blocuri (cadre pagina) si in care se
salveaza numai o parte din maparile realizate. Acest registru asociativ este numit TLB
(Translation lookaside buffer).
8.Algoritmul de inlocuire a paginilor (windows si linux)
Daca un proces are nevoie sa incarce o pagina virtuala in memoria fizica si nu
exista pagini fizice libere, sistemul de operare trebuie sa elibereze o pagina din memorie,
renuntand la una activa. Daca, spre exemplu, pagina la care se va renunta provine dintr-o
imagine sau un fisier asupra caruia nu s-au facut modificari, pagina nu trebuie sa fie
salvata, ci pur si simplu se elibereaza, data viitoare cand este nevoie de ea fiind incarcata
din nou din fisierul original. Daca insa asupra paginii s-au adus modificari, atunci
sistemul de operare trebuie sa salveze intr-un fel aceasta pagina modificata pentru a o
putea accesa mai tarziu. Acest fel de pagina se numeste “dirty page”. Atunci cand aceasta
este stearsa din memorie, ea este salvata intr-un fisier special numit swap file.
Daca algoritmul de swap, care se foloseste pentru a decide ce pagina sa fie stearsa
si ce pagina sa fie salvata, nu este eficient atunci are loc un eveniment numit “thrashing”.
In acest caz paginile sunt scrise si citite incontinuu din memorie, lucru ce face sistemul de
operare sa devina greu de apelat. Setul de pagini pe care le foloseste un proces se
numeste “working set”, iar un swap eficient asigura faptul ca toate procesele au “working
set”-ul complet in memoria fizica.
Pentru a determina paginile care pot fi inlaturate din memoria fizica, Linux
utilizeaza tehnica LRU (Least Recent Used). Astfel, fiecarei pagini din memorie ii este
asociata o varsta, ce se modifica la fiecare accesare a paginii. Cu cat ea este accesata mai
des cu atat ea este mai “tanara”. Cu cat pagina este mai “in varsta” cu atat devine un
candidat mai bun pentru swapping. In cazul unui sistem de operare care foloseste
paginarea pentru managementul memoriei, algoritmii de inlocuire a paginilor decid ce
pagina din memorie sa scrie in swap sau care sa stearga in momentul in care este nevoie
ca memoria sa fie alocata unei noi pagini.
Calitatea unui algoritm este data de timpul in care se face inlocuirea. Cu cat timpul
este mai scurt, cu atat consideram algoritmul mai bun. Un algoritm de inlocuire a
paginilor incearca sa determine ce pagina ar trebui sa fie inlocuita astfel incat sa aiba un
timp de acces cat mai rapid si in asa fel incat acea pagina sa nu fie imediat folosita.
Algoritmii pot fi locali sau globali. Atunci cand algoritmul selecteaza sa
inlocuiasca o pagina in memoria locala a procesului cu o alta pagina din aceeasi
memorie, algoritmul este de tip local. In cazul in care pagina aleasa din orice parte a
memoriei, algoritmul este de tip global. Algoritmii locali partitioneaza memoria in asa fel
incat sa se poata determina cate pagini sa fie ferite unui proces sau unui grup de procese.
Cele mai cunoscute forme de partitionare sunt “fixed artitioning” si “balanced set”,
algoritmi bazati pe modelul working set. Marele avantaj al acestor algoritmi il reprezinta
stabilitatea: fiecare proces isi poate face un management al paginilor independent de orice
structura globala de date. Multi algoritmi returneaza doar un pointer catre pagina in care
urmeaza sa fie scrisa noua pagina. Din pacate aceasta poate fi si de tipul “dirty page”, caz
in care durata scrierii unei noi pagini ar fi mult mai mare. De aceea, in calculatoarele
moderne exista ideea de precuratare. Acest mecanism incepe procesul de stergere asupra
paginilor ce urmeaza a fi inlocuite. Ideea este aceea ca pana in momentul in care va fi
nevoie de pagina respectiva din memorie , ea sa fie deja curata. Acest algoritm trebuie sa
determine ce pagini vor urma sa fie inlocuite, pentru a nu sterge in mod inutil.
Daca rulam orice apropiat de un system de operare modern, interactionam cu
siguranta cu un swap file. Deja am trecut in revista bazele acestui fenomen: swap files
permit sistemului de operare sa prioritizeze paginile frecvent folosite in memoria
principala si sa le mute pe cele mai putin folosite pe disk. In esenta se intampla foarte
multe in spatele acestei idei; propun un ghid simplu la teoria si practica de fisiere swap in
Linux, si cum se pot aranja lucrurile in beneficiul utilizatorului.
Managerul de memorie imparte memoria virtuala in bucati de aceeasi dimensiune
numite pagini. O pagina este cea mai mica suma pe care sistemul de operare o va aloca,
in raspuns la solicitarile de la programe. Este de asemenea cea mai mica unitate de
transfer intre memoria principala si orice alta locatie, cum ar fi un hard disk.
Dimensiunea unei pagini este de obicei stabilit de catre nucleul oricarui sistem de
operare. Nucleul controleaza accesul la diferitele resurse ale calculatorului si permite
celorlalte componente — hardware si software — sa interopereze.
kernel = nucleu
O dimensiune de pagina tipic pentru un sistem desktop modern este de
aproximativ 4 kilobytes:
Paginile sunt alocate in memoria fizica printr-o mapare speciala numita
translatarea adreselor. Aplicatiile nu stiu unde se afla in spatiu fizic, acestea doar vad
paginile in uz.
Managerul de memorie stie cum sa contopeasca diferite locatii de reserva pentru a
oferi suport de captare de memorie virtuala contigua. Prin actualizarea mecanismului de
translatare al adreselor o pagina virtualaintotdeauna puncteaza la pagina fizica corecta,
managerul de memorie mutand pagini de jur imprejur in memoria fizica, fara a afecta in
mod direct aplicatiile.
Nu fiecare memorie suplimentara afiseaza aceleasi depozite si caracteristici ale
vitezei. Daca tipuri diferite ale memoriei afiseaza diferite caracteristici, managerul
memoriei poate exploata aceste diferente spre a optimiza performantele sistemului. Astfel
se pot lua decizii inteligente in legatura felul in care ar trebuie repartizate si unde.
Hard-disku-urile sunt mai slabe cu cateva ordine de marime si mai lente la gasirea
datelor decat memoria principala. Astfel, managerul de memorie trebuie sa echilibreze
atent cererea de memorie impotriva diferitelor tipuri de aprovizionare.
Tipuri de pagini
In Linux se gasesc 4 tipuri de pagini:
Paginile nucleu: detin continutul programului a nucleului in sine. Spre
deosebire de alte tipuri, acestea sunt stabilite in memorie o data ce sistemul de operare a
fost incarcat si nu sunt niciodata mutate.
Paginile de program: stocheaza continutul programelor si librariilor.
Aceste sunt read-only, asadar nu este nevoie de update-uri.
Paginile de rezerva: stocheaza continutul fisierelor pe disk. Daca aceasta
pagina a fost schimbata in memorie, adica un document la care lucrez, va fi nevoie la un
moment dat sa fie scrisa in afara disk-ului pentru a sincroniza schimbarile.
Paginile anonime: pagini care nu prezinta suport deloc pe disk. Cand un
program are nevoie de memorie alocata pentu a performa sau pentru a inregistra
informatii, acestea isi vor gasi locul in pagini anonime.
Gestiunea tabelului de pagini
In Linux se prefera mentinerea conceptului de tabel de pagini pe 4 niveluri, ceea
ce inseamna ca diferentierea intre diferite tipuri de pagini este greu de facut, iar paginile
sunt identificate prin flag-urile lor sau prin ceea ce listeaza, mai mult decat dupa obiectele
carora apartin.
Arhitecturile care isi gestioneaza diferit blocul MMU emuleaza tabelele de pagini
pe niveluri multiple. In Linux, nivelurile logice pentru paginare sunt: directorul global de
pagini (PGD), directorul superior de pagini (PUD), directorul intermediar de pagini
(PMD), si tabelul de pagini (PTE). Pentru arhitecturile cu doar doua niveluri de paginare,
PUD si PMD sunt eliminate la compilare. Fiecare pagina are alocat un numar unic(PFN)
iar fiecare tabel de pagini accesat(dintre primele trei) contine valoarea PFN de la
urmatorul nivel.
Figura urmatoare arata modul in care o adresa virtuala poate fi “sparta ” intr-o
serie de domenii, fiecare oferind o mapare intr-o anumita pagina.
Algoritmul prietenului
Sistemul “prietenului” (buddy_2) este un algoritm simplu de alocare a memoriei.
Principalul sau scop este de a reduce pe cat posibil numarul intreruperilor esterne si, in
acelasi timp, de a permite alocarea si realocarea rapida a paginilor in memorie. Pentru a
reduce numarul interpretarilor externe, paginile adiacente din memorie . pentru a reduce
numarul intreruperilor externe, paginile adiacente dun memorie sunt grupate in liste de
diferite dimensiuni. Acest lucru permite ca toate blocurile formate din doua pagini sa se
afle intr-o lista, blocurile formate din 4 pagini in alta lista etc. Daca exista o cerere de 4
pagini adiacente, aceasta poate fi satisfacuta prin verificarea blocurilor de 4 pagini libere.
Daca un bloc de 8 pagini este liber, acesta se va imparti in doua blocuri de 4
pagini, unul din ele va fi trimis catre cerere iar celalalt va fi alocat listei cu blocuri de 4
pagini. Acest lucru evita impartirea blocurilor libere cu un numar mare de pagini atunci
cand o cerere poate fi satisfacuta de un bloc cu un numar mai mic de pagini, reducandu-
se astfel fenomenul de fragmentare externa. De asemenea, adresa fizica a primei pagini
trebuie sa fie un multiplu al dimensiunii blocului.
Exemplu: un bloc de dimensiune 2n trebuie sa fie aliniat cu 4kx2n, unde k este
numarul de pagini si n un multiplu al lui 2.
In schimb, cand o pagina de un anumit rang este eliberata din memrie, se
realizeaza o incercare de a o ingloba in blocul corespunzator ei (blocul “prieten”) de
acelasi rang (daca acesta este liber), permitand astfel blocurilor de rang superior sa
ramana libere. Acest procedeu are loc in mod recursiv, pana cand nu mai este posibila o
asociere a blocurilor de acelasi rang, adica, pana cand nu mai ramane decat un singur
bloc de rang superior. Blocul ramas liber este apoi alocat listei blocurilor libere careia ii
corespunde. Acest procedeu se numeste fuziune. Linux foloseste liste de 1, 2, 4, 8, 16, 32,
64, 128, 256 si 512 blocuri de pagini.
Alocarea paginilor de memorie
Ibntr-un sistem exista mai multe cereri asupra paginilor fizice. De exemplu, cand
se incarca o imagine in memorie, sistemul de operare trebuie sa aloce pagini. Acestea vor
fi eliberate in momentul in care imaginea nu mai este procesata si este descarcata. O alta
utilizare a paginilor din memorie este stocarea de date specifice kernel-ului, cum este
tabelul propriu de pagini. Mecanismul si structurile de date folosite pentru alocarea si
eliberarea memoriei sunt elementele critice in mentinerea eficientei memoriei virtuale.
Linux foloseste algoritmul buddy_2pentru a aloca si de-aloca eficient blocuri de
pagini. Paginile sunt alocate in blocuri cu valori puteri ale lui 2. Aceasta inseamna ca se
pot aloca blocuri de o pagina, doua pagini, patru pagini s.a.m.d. Atat timp cat in memorie
exista destule pagini libere pentru a rezolva aceasta cerere (numarul paginilor libere
depaseste numarul minim al acestora), codul de alocare va cauta in zona libera(free area)
un bloc egal ca dimensiune cu cel solicitat (ca in figura)
Fiecare element din zona libera contine o harta a blocurilor libere si alocate pentru
o alta dimensiune.
Exemplu: al doilea element al sirului contine i harta de memorie care descrie
blocurie (libere si alocate) avand lungimea de pagini.
Algoritmul de alocare cauta la inceput un bloc de pagini egal ca dimensiune cu cel
solicitat, urmarind lantul de pagini libere care sunt stocate in elementul list din structura
zonei libere. Acest element este transparent procesului de referire la structurile de tip
pagina, nefiind reprezentat in zona libera din figura.
Daca nu exista blocuri libere de dimensiunea solicitata, atunci se vor cauta blocuri
cu urmatoarea dimensiune (dubla fata de cea solicitata). Acest proces va continua fie
pana cand intreaga zona libera va fi scanata, fie pana cand se va gasi blocul potrivit. Daca
blocul gasit este de dimensiune mai mare decat cea solicitata, atunci acesta va fi spart in
blocuri de dimensiuni mai mici, pana cand se ajunge la dimensiunea potrivita. Datorita
faptului ca dimensiunile blocurilor sunt puteri ale lui 2, procesul de impartire este simplu,
dimensiunea injumatatindu-se de fiecare data. Blocul liber esye stocat in cea mai
apropiata lista, iar blocul alocat este returnat apelantului.
Exemplu: in figura de mai sus, daca se solicita un bloc de doua pagini, primul
bloc de 4 pagini (incepand cu numarul de cadru 4) va fi spart in doua blocuri de cate doua
pagini. Primul (incepand cu numarul de cadru 4) va fi returnat apelantului, iar cel de-al
doilea (cu numarul de cadru 6) va fi stocat ca bloc de doua pagini in elementul 1 din sirul
continut in zona libera.
8.1 Algoritmul optim de inlocuire a paginilor (teoretic- Belady)
Acest algoritm este cunoscut si ca OPT si functioneaza in felul urmator: cand o
pagina trebuie copiata de pe disc in memorie, sistemul de operare muta din memorie pe
disc, continutul paginii care va fi folosita cel mai tarziu in proces, facand loc noii pagini.
De exemplu o pagin care va fi folosita in urmatoarele 10 secunde va fi mutata din
memorie pe disc pentru a face loc unei pagini care va fi folosita in urmatoarele 2 secunde.
Algoritmul Belady este unul teoretic, neputand fi implementat de un sistem de
operare, deoarece nu se poate sti exact cat va dura pana can va fi folosita o pagina din
memorie.
8.2 Algoritmul Not Recently Used (NRU)
El pastreaza in memorie paginile care au fost folosite cel mai recent. Principiul
este urmatorul: cand se adreseaza o pagina, i se atribuie un bit (bit de adresare). La fel
cand se aduc modificari asupra paginii, i se atribuie un nou bit, de modificare. La un
anumit interval de timp se reseteaza bitii fiecarei pagini. Paginile se impart in urmatoarele
categorii:
clasa0: neadresata, nemodificata
clasa1: neadresata, modificata
clasa2: adresata, nemodificata
clasa3: adresata, modificata
Algoritmul NRU alege la intamplare o pagina din clasele inferioare pentru
inlocuire. In acest algoritm, o pagina adresata este mai importanta decat una modificata.
8.3 First-in, First-out (FIFO)
Algoritmul FIFO(primul intrat, primul iesit) presupune eliminarea oaginii care a
fost incarcata prima, indiferent de ultimul moment de referire al paginii respective.
Fiecare pagina are un contor, ele fiind aranjate intr-o coada. In momentul in care se
adaoga o pagina, aceasta va avea contorul 0 iar contorul paginii imediat urmatoare se va
incrementa cu 1. In momentul in care o pagina trebuie eliminata, se va alege mereu cea
cu valoarea contorului cea mai mare(pagina cea mai din dreapta) iar in stanga va ramane
un loc liber pentru adaugarea unei pagini, care va avea contorul 0.
Acest algoritm este foarte ieftin si cere foarte putine resurse din partea sistemului
de operare insa are performante slabe comparativ cu alti algoritmi, din aceasta cauza este
rar folosit.
8.4 Second Chance
Second Chance este un algoritm inspirat de FIFO, dar cu performante mult mai
bune, diferenta de pret fiind foarte mica. Functioneaza verificand pagina cu contorul cu
cea mai mare valoare insa in loc sa o extraga, ca in algoritmul FIFO, Second Chance
ofera o a doua sansa paginii, verificand daca are sau nu fixat bitul de referinta. Daca
acesta nu este setat, algoritmul functioneaza in continuare ca FIFO, mutand pagina din
memorie. Daca bitul de referinta este setat, contorul paginii este adus la 0, pagina fiind
practic inserata din nou in coada, ca si cum ar fi o pagina noua.
8.5 Clock
Este o varianta mai eficienta a FIFO decat Second Chance, intrucat paginile nu
trebuie sa fie mutate constant in celalalt capat al cozii, desi functia pe care o indeplineste
este aceeasi. Acest algoritm tine o lista circulara a paginilor din memoria virtual, cu un
bit de adresare in dreptul fiecarei pagini. Algoritmul are mereu un pointer catre cea mai
veche pagina din lista. Cand este nevoie de o pozitie noua, algoritmul inspecteaza intai
cea mai veche pagina si in cazul in care bitul de adresare este 0 o inlocuieste. Daca nu, se
trece la urmatoarea pagina ca vechime si asa mai departe.
8.6Least Recently Used (LRU)
Principiul acestuia este ca paginile ce au fost foarte folosite in ultima perioada de
timp (determinata) vor fi folosite mult si in viitor deci ele ar trebui pastrate. Teoretic
acesta este unul dintre cei mai eficienti algoritmi numai ca este foarte costisitor.
Exista totusi cateva forme ale acestui algoritm care incearca sa reduca din costuri,
pastrand in acelasi timp performanta.
Cea mai costisitoare varianta a LRU este cea de tip coada. Aceasta implica
realizarea unei liste cu toate paginile din memorie, aranjate in ordinea utilizarii. La
sfarsitul listei se afla cea mai putin utilizata pagina recenta iar in varf cea mai utilizata.
Intrarile din lista trebuie rearanjate dupa fiecare accesare a listei, ceea ce face metoda sa
fie foarte lenta.
O alta versiune a acestei metode are nevoie de un suport hardware si functioneaza
pe baza unui counter. De fiecare data cand o pagina este accesata, aceasta primeste o
valoare egala cu a counter-ului in momentul accesarii. Cand o pagina trebuie mutata,
sistemul de operare selecteaza pagina cu counterul cel mai mic si o muta. Costul
implementarii acestei metode este foarte ridicat datorita tehnologiei necesare
implementarii counterului.
Un mare defect al LRU este acela ca daca el gestioneaza la un moment dat N
pagini, iar o aplicatie lucreaza cu un loop de N+1 pagini, la ultima operatie va rezulta o
eroare. Versiunile derivate ale LRU, incerca, pe de-o parte sa rezolve problema costului
ridicat si pe de alta parte sa elimine aceste erori.
Exemplu: LRU-K reprezinta o imbunatatire fata de LRU in ceea ce priveste
consumul de timp. ARK reprezinta un LRU ce pastreaza si o istorie a pagnilor pe care le-
a sters.
8.7 Algoritmul RANDOM.
Dupa cum spune si numele, paginile vor fi eliminate din memoria virtuala aletor.
Acest procedeu elimina costurile legate de realizarea unui sistem de monitorizare al
paginilor. De obicei are rezultate mai bune decat FIFO, si in cazul ciclurilor, mai bune
decat LRU, desi in general cel din urma se descurca mai bine in practica.
Sistemul de operare OS/390, construit pentru mainframe-urile de la IBM, foloseste
algoritmul LRU, iar cand performantele acestuia scad se apeleaza la algoritmul Random.
8.8 Not Frequently Used
Algoritmul NFU genereaza mai putine semnale de eroare(page fault) decat LRU
unde tabelul de pagini contine multi poiteri cu valori nule. Acest algoritm foloseste un
counter pentru fiecare pagina. La fiecare interval de ceas, totate paginile referite in acel
interval vor afvea counterul incrementat cu 1. Astfel se poate determina cat de frecvent a
fost folosita o pagina, iar pentru eliminare va fi aleasa pagina cu valoarea counterului cea
mai mica.
Viteza acestui algoritm este mica datorita numaratorului.
Marea problema a acestuia este ca tine cont de frecventa de accesare a paginii dar
nu si de durata cat a fost ea folosita, el lovindu-se de o reala problema la pornirea unui
sistem de operare. In acest caz, unele pagini sunt accesate in primul pas si folosite pe o
durata lunga de timp, dupa care, in pasul al doilea, alte pagini sunt folosite frecvent insa
pentru durate scurte de timp. La o cerere de inlocuire, algoritmul va inlocui, deci, o
pagina ce a fost folosita la pornire, lucru ce va rezulta, desigur, intr-o eroare.
8.9 Aging
Este urmasul algoritmului NFU, imbunatatirea adusa fiind ca in acest caz este
luata in calcul si durata de folosire a unei pagini. In acest caz, in loc de o simla
incrementare a contorului, el este intai mutat la dreapta cu o unitate. Daca bitii de
referinta ai unei pagini arata asa pe durata a 6 perioade ale ceasului: 100110, atunci
contorul a fost incrementat astfel: 10000000, 01000000, 00100000, 10010000, 11001000,
01100100.
Aceasta metoda face ca paginile folosite mai recent dar mai putin frecvent sa aiba
o prioritate mai ridicata decat paginile accesate frecvent in trecut. Cand este nevoie de o
pagina inlocuita se va alege pagina cu cel mai mic contor.
Problema acestui algoritm este ca poate monitoriza doar ultimele 16 sau 32 de
intervale, astfel doua pagini pot avea contorul 00000000, chiar daca una a fost accesata
cu 9 intervale in urma iar alta cu 100. Totusi, cunoasterea folosirii in ultimele 16 intervale
este suficienta pentru o decizie aproape optima astfel, Aging fiind considerat un algoritm
aproape perfect pentru un pret moderat.
Comparatie intre algoritmi
Graficul din figura urmatoare reda comparative performanta(raporatata la numarul
de exceptii page fault aparute la 1000 de referinte) in functie de numarul de cadre apelate,
pentru 4 dintre algoritmi: FIFO, Clock, optim si LRU
9. Securitatea si protectia
memoriei
9.1 Problema securitatii
Securitatea este acea parte care se ocupa cu protejarea integritatii informatiilor
stocate in sistem (date si instructiuni), precum resursele fizice ale sistemului.
Incalcarile de securitate a sistemului pot fi accidentale sau intentionate( de tip malware).
Cel mai usor de protejat este impotriva abuzurilor accidentale decat impotriva utilizarii
abuzive malware.
9.2 Notiuni si niveluri de securitate
Pentru protectia unui sistem avem patru niveluri de securitate:
-La nivel de persoana – alegerea corecta si educarea utilizatorilor
-La nivel fizic – protectia zonelor care contin sistemele de calcul
-La nivelul sistemului de operare - securizarea accesului, protectia resurselor Sistemului
de operare (memorie, fisiere), securizarea aplicatiilor
-La nivelul retelei – securizarea accesului de la distanta, filtrarea pachetelor de
compromitere a retelei
In subcapitolele urmatoare ne ocupam de securitatea la nivelul sistemului de
operare (securizarea memoriei).
9.3 Securitatea Sistemului de Operare – Securitatea si
protectia resurselor – Memoria
Organizarea memoriei poate sa fie segmentara sau liniara. Procesorul are un
mechanism de translatare a adreselor care se foloseste in implementarea memoriei virtual.
Acest mecanism este util pentru protejarea informatiei din memorie. Mecanismele de
translatare a adreselor sunt procese care atribuie si mapeaza adresele logice in adrese
fizice de memorie. Cele de scheme de translatare sunt prin paginare si prin segmentare.
Pentru ca sistemul sa efficient in cazul maparii prin paginare se folosesc tabele
associative de mare viteza pentru ca numarul liniilor este mai mic decat numarul de
pagini in care se salveaza numai o parte din maparile realizate.
Metodele de securitate si protectie in cazul sistemelor de operare sunt legate de
implementare memoriei virtuale.
Multiprogramarea conduce la conceptul de proces. Un proces este constituit dintr-un
program aflat în executie plus orice stare necesara pentru continuarea rularii sale.
Partajarea timpului (“time-sharing”) este o varianta a multi-programarii care partajeaza
UCP si memoria între diferiti utilizatori simultani, iar mecanismul de partajare da iluzia
ca toti utilizatorii au propriile masini. Astfel ca , in oricare dintre variante, trebuie sa fie
posibil sa se comute de la un proces la altul. Aceasta comutare este numita comutare de
proces sau comutare de context.
Un proces trebuie sa se execute corect indiferent daca se executa continuu de la start pana
la terminare, sau daca este intrerupt în mod repetat pentru a se face comutarea catre alte
procese. Responsabilitatea mentinerii comportarii corecte a proceselor cade atat în
sarcina resurselor hardware, care asigura salvarea si restaurarea corecta a proceselor ce
ruleaza pe UCP cat si in sarcina sistemului de operare care trebuie sa garanteze ca un
proces nu interfereaza cu celelalte si ca un proces nu poate modifica datele altor procese.
Aceasta inseamna asigurarea protectiei datelor de catre sistemul de operare. In afara de
protectie, sistemul de operare permite, în anumite conditii, si partajarea codului si a
datelor intre diferite procese pentru salvare de spatiu de memorie prin reducerea
numarului de copii de informatii identice.
Cel mai simplu mecanism de protectie este constituit de o pereche de registre care
verifica fiecare adresa, astfel incat sa nu se permita accesul în afara unor limite alocate în
spatiul de adrese. Aceste register sunt numite registru - baza si registru limita. O adresa
este valida daca se încadreaza între cele doua adrese continute în registre:
Baza = Adresa = Limita
La unele sisteme adresa este considerata ca un numar fara semn, care se aduna
întotdeauna la o adresa de baza, astfel ca testul de adresa limita se reduce la:
(Baza + Adresa ) = Limita
Pentru asigurarea protectiei sistemul de operare (SO) are trei responsabilitati principale:
1. Sa furnizeze cel putin doua moduri de executie indicand ca procesul aflat în rulare este
un proces utilizator, sau un proces al sistemului de operare. La diferite SO ultimul tip de
proces este numit in diferite feluri: proces kernel (nucleu), proces supervizor, sau proces
executiv.
2. Sa prevada o portiune a starii CPU pe care procesul utilizator o poate doar citi, dar nu o
poate scrie. Aceasta include registrele baza / limita, indicatori (biti) pentru moduri
utilizator / supervizor si indicatori pentru validare / invalidare evenimente de tip exceptie.
3. Sa prevada un mecanism prin care UCP poate trece din mod utilizator (user) în mod
supervizor si viceversa. Primul sens de trecere este specific apelurilor sistem (“system
calls” – apeluri de servicii oferite de SO), implementate ca instructiuni speciale care
transfera temporar controlul la o locatie precisa din spatiul de cod al supervizorului.
Registrul contor de program corespunzator locului unde se face un apel sistem este salvat,
iar UCP trece în mod supervizor. Revenirea la modul utilizator este similara cu cea
produsa la o revenire din procedura.
Adresele de baza si limita constituie minimul unui sistem de protectie. Mecanismul
memoriei virtual ofera alternative mai complexe si mai sigure decat modelul simplu prin
baza si limita . Asa cum s-a vazut, adresele virtuale sunt translatate în adrese fizice pe
baza unor tabele de translatare. Acest mod de mapare, prin tabele, ofera posibilitatea
introducerii de informatii pentru controlul erorilor de program (intentionate sau nu) care
încearca sa treaca peste mecanismele de protectie. Cea mai simpla cale este introducerea
unor indicatori de permisie pentru fiecare pagina sau segment. De exemplu pot exista
indicatori care sa permita doar citire, doar executie, sau care sa interzica accesul unui
proces utilizator la anumite pagini / segmente.
Fiecare proces poate face adresare doar catre paginile proprii de memorie, procesul
utilizator neavand dreptul sa modifice tabelele sale de pagina / segment.
Protectia poate fi extinsa chiar pe mai mult decât doua niveluri (nu doar utilizator si
supervizor), privite ca si inele concentrice de protectie, in centru gasindu-se nivelul de
protectie cel mai inalt. În aceasta ierarhie de niveluri de protectie un program poate
accesa doar date de pe nivelul sau de protectie si de pe nivelurile inferioare în ierarhie.
Poate face însa operatii de apelare (call) a serviciilor sistemului de operare, servicii
oferite de rutine ce se afla pe niveluri superioare de protectie. Adesea se face comparatia,
in oarecare masura nefericita, cu clasificari de tip militar ale sistemelor: top – secret,
secret, confidential si neclasificat. Programele utilizator (“civilii” in exemplul militar) au
doar dreptul de acces la nivelul de protectie cel mai de jos: “ne-clasificat. La sistemele de
protectie de tip inele concentrice, deosebirea fata de exemplul anterior, este ca se pot face
apelari la rutine situate pe niveluri superioare de protectie, daca exista “chei” de acces
catre acele niveluri. Poate exista dreptul de apelare a unor servicii ale sistemului de
operare, prin mecanismul de comutare a proceselor.
Asa cum am pomenit si mai sus, informatia de protectie este setata in registre speciale
atasate fiecarei intrari in tabelele de translatare, registre setate doar de rutine de control al
sistemului de operare. Drepturile de acces pot fi de tipul:
a. Atribuirea de privilegii complete de citire si scriere. Aceste drepturi se atribuie
programului atunci cand se executa propriile instructiuni.
b. Read-only (protectie la scriere). Protectia la scriere este utila la operatiile de partajare
a unor rutine de sistem (utilitare, biblioteci, etc.).
c. Execute only (program protection). Protejeaza programul la copiere. Restrictioneaza
referirea la segment doar in timpul fazei de fetch a instructiunii si nu si in timpul fazei de
executie. Asta permite utilizatorului sa execute instructiunile segmentului de program,
dar nu permite citirea instructiunilor ca date cu scopul de a copia continutul lor.
9.4 Metode si clasificari de securitate si protectie
Intre toate amenintarile posibile la sistem si la reteau de securitate exista o relatie
directa si intre solutiile de securitate.
Oameni care se ocupa se securitatea sistemelor sustin teoria de aparare pe mai multe
straturi.
Exista 4 clasificari de securitate: A,B,C si D.
Cea mai mica protectie este reprezentata de divizia D. Aceasta include o clasa si este
utilizata pentru sistemele care nu au reușit să îndeplinească cerințele de la oricare din
celelalte clase de securitate. Exemple: MS-DOS si Windows 3.1.
Divizia C ofera protectie discretionara si responsabilitati de utilizatori si actiunile lor prin
utilizarea capacitatilor de audit. Aceasta se imparte in 2 niveluri: C1 si C2.
Un sistem de calcul de clasa C1 include unele forme de control care permite utilizatorilor
sa poata proteja unele date private si ca alti utilizatori sa distruga accidental datele. O
clasa C1 este un mediu in care utilizatorii acceseaza datele pe aceleasi niveluri de
sensibilitate. Exemple de versiuni de sisteme de operare care sunt de clasa C1: UNIX.
Totalul tuturor sistemelor de protectie intr-un sistem informatic (hardware, software,
firmware) este cunoscuta ca un TCB al sistemului C1 care controleaza accesul intre
utilizatori si fisiere. Astfel se permite utilizatorului sa se specifice si sa controleze
schimbul de obiecte. TCB impune ca utilizatorii sa se identifice ianinte de inceperea unei
activitati in care TCB urmeaza sa o medieze. Aceasta identificare se realizeaza printr-un
mecanism protejat sau parole. TCB protejeaza datele de autentificare astfel incat acestea
sunt inaccesibile utilizatorilor neautorizati.
Clasa C2 adauga un control al accesului la nivel individual la cerintele unui sistem de
clasa C1.
De exemplu, pot fi specificate drepturile de acces ale unui fisier la nivelul unui singur
individ. Sistemul TCB se protejeaza de modificarile codului sau datelor . De asemenea
nicio informatie produsa de un utilizator nu este valabila altui utilizator care acceseaza un
obiect de stocare care a fost lansat inapoi in sistem.
Divizia B are toate proprietățile unei clase de sistem C2.
In plus, acorda o eticheta de sensibilitate la fiecare obiect.
Clasa B1
TCB mentine eticheta de securitate a fiecarui obiect in sistem; eticheta este utilizata
pentru deciziile referitoare la controlul accesului obligatoriu. De exemplu, un utilizator
la nivel confidential nu poate accesa un fisier de la nivele secrete. TCB denota si nivelul
de sensibilitate la partea de sus si de jos a fiecarei pagini. In plus fata de autentificarea
username-password TCB mentine, de asemenea, clearance-ul si autorizatiile de utilizatori
individuali si va sprijini cel putin doua niveluri de securitate. Aceste niveluri sunt
ierarhice, astfel incat un utilizator poate accesa orice obiect care transporta etichete de
sensibilitate egala sau mai mica decat clearance-ul sau de securitate.
Clasa B2
Extinde etichete de sensibilitate pentru fiecare resursa de sistem, cum ar fi obiectele de
stocare. Dispozitivele fizice sunt atribuite minim si maxim nivelurilor de securitate care
utilizeaza sistemul pentru a impune constrangeri impuse demediile fizice in care
dispozitivele sunt amplasate. In plus, clasa B2 suporta canale sub acoperire si audit de
evenimente care ar putea duce la exploatarea unui canal sub acoperire.
Clasa B3
Permite crearea de liste de control al accesului, care denota utilizatorii sau grupurile care
nu au acordat acces la un anumit obiect. TCB, de asemenea, contine un mecanism de
monitorizare a evenimentelor care pot indica o incalcare a politicii de securitate.
Mecanismul notifica administratorului de securitate si, in cazul in care este necesar, se
incheie evenimentul in mod perturbator.
Clasa A1
Arhitectural clasa A1 este o clasa asemanatoare cu clasa B3.
Diferenta este ca se foloseste proiectarea formala si tehnicile de verificare, care acorda un
grad ridicat de asigurare.
Pe langa segmentare si paginarea memoriei virtuale, ca modalitate de securitate si
protective putem avea si chei de protectie.
Cheile de protective sunt un mecanism de protecţie care imparte memoria fizica in
blocuri de o anumita dimensiune. Blocurile au o valoare numerica numita cheie de
protectie, la fel si procesele.
Principiul de funtionare:
Se verifica daca valoarea cheii procesului corespunde cu valoarea cheii din blocul de
memorie accesat. Daca cele 2 chei au aceleasi valori se poate accesa memoria, in caz
contrar aruncandu-se o exceptie.
9.5 Concluzii
Pentru ca un sistem sa functioneze optim si sigur accesul la memorie trebuie sa fie
cat mai rapid dar in acelasi timp sa se faca si sigur pentru ca datele sa nu se piarda sau sa
se distruga. Am vazut ca metodele de securitate si protectie in cazul sistemelor de operare
sunt legate de implementare memoriei virtuale. De asemenea securitatea memoriei se
imparte in 4 clase : A, B, C, D. Metodele de protectie si securitate a memoriei sunt:
segmentarea si paginarea memoriei virtual si cheile de protectie.
BIBLIOGRAFIE
1. http://elf.cs.pub.ro
2. en.wikipedia.org
3. http://so-usb.blogspot.ro
4. Tanenbaum - Modern Operating Systems 2nd Ed
5. www.scribd.com
6. http://www.linux-tutorial.info
7. Radu Radescu – Arhitectura Sistemelor de Calcul
8. http://www.elcom.pub.ro
9. Addison Wesley – Silberschatz, Galvin, Gagne – Operating System
Concepts, 8th
Ed.