A memória-allokáció azokra a technikákra és algoritmusokra vonatkozik, amelyek a RAM-nak egy számítógépes programhoz való lefoglalásához szükségesek.
Az allokáció szimmetrikus működését általában memória felszabadításnak nevezik (beszélhetünk deallocation-ről vagy restitúcióról is).
A számítógépes program lényegében két erőforrást emészt fel: a processzorok feldolgozási idejét és az adattárolási helyet. A gépekben a tér lehet illékony véletlen hozzáférésű memória vagy állandó tömeges memória .
Három memóriaallokációs stratégia létezik: statikus, dinamikus veremkiosztás és dinamikus halomallokáció . A statikus allokációt főként lefordított programozási nyelveken hajtják végre ( C , C ++ , Pascal …). Az értelmezett nyelvek ( PHP , Python , Perl stb.) Csak igény szerint tudnak memóriát lefoglalni a szkript végrehajtása során.
Mindegyik stratégiának megfelel a program vagy szegmens memóriaterülete . Ezeknek a szegmenseknek a neve szöveg (statikus), verem és halom .
Allokációs módszer | Használt memóriaterület | Előny | Programozási nyelv | |||
---|---|---|---|---|---|---|
összeállítva (C, C ++, Pascal stb.) |
értelmezve (PHP, Python, Perl stb.) |
|||||
statikus | szöveg , adat vagy BSS | a futásidő hatékonyabb kihasználása | Igen | nem | ||
dinamikus | a verem ( verem ) | (lexikális vagy automatikus) | Kazal | a futásidő hatékonyabb kihasználása | Igen | Igen |
a munkahelyen ( halom ) | (dinamikus memória-allokáció) | halom | a memóriaterület hatékonyabb kihasználása | Igen | Igen | |
Megjegyzések | A statikus allokációt főként lefordított programozási nyelveken hajtják végre (C, C ++, Pascal…). | Az értelmezett nyelvek csak igény szerint tudnak memóriát lefoglalni a szkript végrehajtása során. |
A statikus allokáció a program inicializálásakor, a tényleges végrehajtás előtt történik. A statikusan lefoglalt területet már előre lefoglalták a program futtatható fájljában, amikor az operációs rendszer betölti a programot a memóriába a futtatásához.
A memória statikus kiosztása egy programhoz a következőket jelenti:
Futás közben statikus kiosztásra nem kerülhet sor.
A statikus allokáció előnye lényegében a teljesítmény szempontjából van, mivel a futásidejű dinamikus allokáció költségei elkerülhetők: a statikus memória azonnal használható.
A szokásos operációs rendszereken a statikusan lefoglalt memória a program szövegszegmensébe , adatszegmensébe vagy BSS szegmensébe kerül, ennek a memóriaterületnek a sorsától függően (fenntartott, inicializált, csak olvasható stb.).
A dinamikus kiosztás a program futása alatt történik, ami azt jelenti, hogy a dinamikusan lefoglalt hely még nincs a program futtatható fájljában, amikor az operációs rendszer betölti a programot a memóriába a futtatásához; az operációs rendszer számára történő helyfoglalás iránti kérelem a program végrehajtása során történik.
Kiosztás a veremben (automatikus)A program futtatása általában a kereteket tartalmazó verem segítségével hívja meg a használt programozási nyelv rutinjait ( funkcióit vagy eljárásait ). Vázlatosan a lexikális változók, azaz a rutin szöveges hatókörében definiált változók:
Ezen allokációkhoz / felszabadításhoz memória szegmenst, verem szegmensnek hívnak . A lexikai változó fogalmát támogató nyelv forráskódjában nincs szükség kulcsszóra: a teret a veremfegyelemnek megfelelően definiálják és felszabadítják .
Egyes nyelvek, például a C vagy a C ++ , a lexikai változók helyett automatikus változókról beszélnek , de ezek ugyanazok.
Munkahelyi juttatásMivel a legtöbb programnak memóriaigénye van a használatuktól függően, a végrehajtás során tetszőleges időpontokban fel kell tudni kérni az operációs rendszert új memóriaterületek kiosztására, és vissza kell tudni állítani ezeket a zónákat a rendszerre ( szabadítsa fel a memóriát). Az operációs rendszer egy táblával kezeli a kupacot, ahova naplóz minden egyes lefoglalt memóriablokkhoz:
A memória kiosztásának és felszabadításának kezelése a programozó feladata .
Lépés | Sebészet | jegyzet |
---|---|---|
Kérelem a program kiosztására | A program kéri az operációs rendszert, hogy foglaljon le memóriaterületet [a kívánt bájtok számának megadásával]. | |
Kiosztás operációs rendszer szerint | Ha a halomban rendelkezésre áll a kért méretű [memória] bájtblokk, az operációs rendszer visszaadja az elérhető bájtok blokkjának kezdőcímét. |
|
A lefoglalt memória használata | A program a kiosztott memóriaterületet saját belátása szerint használja. | |
Kiadási kérelem a program részéről | Amikor a programnak már nincs szüksége a lefoglalt memóriaterületre, felszabadítja azt, jelezve az operációs rendszernek a fenntartani kívánt blokk kezdetének címét, amelyet felszabadítani kíván. | Ha a program nem szabadítja fel a lefoglalt memóriát a kilépés előtt, memóriaszivárgást okoz . |
A szemétszedés programozási nyelvei a programozó számára átláthatóan használják a halomelosztást és a * allokáció / ingyenes primitíveket. Ez utóbbi esetben a szemétszedő lehetővé teszi a fejlesztő számára, hogy ne aggódjon az erőforrások felszabadítása miatt.
VeszélyA felmerülő memóriaszivárgások , valamint a vonali interfésszel rendelkező operációs rendszer (pl. DOS) grafikus felhasználói felülettel (pl. Windows), valamint a kézi memóriakezelő programok egyéb gyakori hibái a halom memória-elosztási hibákban rejlenek.
Példák néhány programozási nyelvreHagyományosan a függvények mallocés freea C nyelvi standard könyvtárak , valamint az operátorok newés a C ++delete nyelv lehetővé teszik a halom memóriájának lefoglalását és felszabadítását.
int UtiliserAllocationDynamiqueDeMemoire ( int Nb ) { // Pointeur vers la mémoire allouée dynamiquement. int *pInt = NULL; // Demander l'allocation dynamique de l'espace mémoire nécessaire pour une liste de «Nb» nombres entiers. pInt = (int *) malloc ( Nb * sizeof(int) ); // Si l'espace mémoire demandé a bien été alloué if ( pInt != NULL ) { // Utiliser l’espace mémoire alloué. // ... // Libérer l'espace mémoire alloué. free (pInt); }// Fin du si. // Retourner le code d'erreur à la routine appelante. return 0; } |
A statikus allokáció a legbiztonságosabb módszer abban az értelemben, hogy:
Ez azonban nagyon merev módszer, és nem elegendő azoknak a programoknak a számára, amelyek igényei kiszámíthatatlanul változhatnak: egy potenciálisan nagy memóriaigénnyel rendelkező program esetében a statikus allokáció pazarláshoz vezetne. Végső soron elsősorban a fordítás idején elérhető állandók vagy számított értékek tárolására szolgál.
A verem kiosztása jó kompromisszumot jelent:
Ha a memóriára vonatkozó igényeket előre ismerjük, és azok arányosak a program bizonyos bemeneti paramétereivel, akkor a veremben történő allokációt prioritásként kell kiválasztani. A nagy memória egymás utáni kiosztása és felszabadítása, a veremfegyelem szerint, teljesítmény- és forrásolvasási problémákat okozhat (a funkcióknak átadott paraméterek száma robbanhat); ezeket a problémákat össze kell vetni a memóriaforrások helyes felszabadításának biztosításával.
A munkahelyen történő kiosztás a legtöbb lehetőséget kínálja, mivel lehetővé teszi a kiosztás és felszabadítás teljesen önkényes ellenőrzését. A manuálisan allokált erőforrásoknak azonban határozatlan élettartama van, vagyis a programozó felelős a kiadásért (és kerülnie kell a csapdákba kerülést, mint a kettős kiadásé, vagyis mondjuk ugyanazon memóriaterület kétszeri felszabadítását). A kupacon lefoglalt memóriára globális változók is hivatkozhatnak (lehetőleg névtérre korlátozva ), amelyek elősegíthetik a közös paraméterek funkcióinak egy csoportját.
A gyakorlatban a legegyszerűbb allokációs módszert részesítik előnyben. Legtöbbször elegendő a verem elosztása. A kupacon történő allokációt csak végső megoldásként használják, összetett adatstruktúrák kezelésére és / vagy amelyek evolúciója nem követi a verem fegyelmét.
Az automatikus memóriafeloldással ( szemétgyűjtő algoritmus ) rendelkező nyelveken, mint például a LISP, a Java vagy a C #, a lefoglalási módot közvetlenül a fordító választja meg .