Alocarea unor cantități uriașe de memorie

Alocarea unor cantități uriașe de memorie

În a patra ediție a ghidului populare sunt elementele de bază ale programării în sistemul de operare Linux. Considerată: folosind C C ++ bibliotecă / și sistem instrumente de dezvoltare stan-dard Organization apel, fișier I / O, procesele de interacțiune, programarea mijloacelor shell, creând interfețe grafice cu instrumente GTK + sau Qt, utilizarea prize etc. descrise compilare. programe, legându-le c biblioteci și să lucreze cu terminalul I / O. Sunt tehnici de scriere aplicații în medii GNOME® și KDE®, de stocare a datelor, folosind programe de baze de date MySQL® și depanare. Cartea este bine structurat, ceea ce face de învățare ușor și rapid.







Pentru programatorii novici Linux

Cartea: Bazele programării în Linux

Alocarea unor cantități uriașe de memorie

Secțiunile de pe această pagină sunt:

Alocarea unor cantități uriașe de memorie

Acum că ați văzut că sistemul de operare Linux depășește limitele modelului de memorie MS-DOS, să facem mai greu pentru ea. 7.2 Informațiile din programul de exerciții solicită alocarea de memorie, mai mult decât fizic acolo în mașină, astfel încât putem presupune că funcția malloc începe să eșueze atunci când se apropie cantitatea maximă de memorie fizică, deoarece kernel-ul și toate celelalte procese care rulează de asemenea, nevoie de memorie.

Exercițiul 7.2. Solicitați toate memoria fizică

Cu ajutorul programului memory2.c vom cere mai multă memorie decât este fizic în mașină. Trebuie să corectați definiția PHY_MEM_MEGS în funcție de resursele fizice ale computerului dvs.

#include
#include
#include
#define A_MEGABYTE (1024 * 1024)
#define PHY_MEM_MEGS 1024 / * Corectați acest număr
corect * /
int principal () char * some_memory;
size_t size_to_allocate = A_MEGABYTE;
int megs_obtained = 0;
în timp ce (megs_obtained <(PHY_MEM_MEGS * 2)) some_memory = (char *)malloc(size_to_allocate);
dacă (some_memory! = NULL) megs_obtained ++;
sprintf (somememory, "Hello World");
printf ("% s - acum alocat. Megabytesn", some_memory, megs_obtained);
> altceva ieșire (EXIT_FAILURE);
>
>
ieșire (EXIT_SUCCESS);
>

Iată o producție ușor abreviată:

$ ./memory3
Hello World - acum alocate 1 Megabytes
Hello World - acum au alocat 2 megabyte
.
Hello World - acum a alocat 2047 megabytes
Hello World - acum a alocat 2048 megabytes

O alta caracteristica interesanta este ca, cel putin pe aceasta masina, programul ruleaza in clipa in care ochiul este incet. Astfel, nu numai că am folosit cu siguranță toată memoria, dar, de asemenea, am făcut-o într-adevăr foarte repede.







Continuați studiul și vedeți cât de multă memorie putem aloca pe această mașină folosind programul memory3.c (exercițiul 7.3). Deoarece este deja clar că sistemul Linux este capabil să se ocupe foarte mult de cererile de memorie, vom aloca 1 Kbyte de memorie de fiecare dată și vom scrie date către fiecare bloc pe care îl primim.

Exercițiul 7.3. Memorie disponibilă

Aici este programul memory3.c. În adevărata sa natură, este extrem de neprietenos pentru utilizator și poate afecta serios mașina multi-utilizator. Dacă sunteți îngrijorat de acest risc, este mai bine să nu-l rulați deloc; dacă te afli în a face acest program, nu va face rău să înveți materialul.

#include
#include
#include
#define ONE_K (1024)
int principal () char * some_memory;
int size_to_allocate = ONE_K;
int megs_obtained = 0;
int ks_obtained = 0;
în timp ce (1) pentru (ks_obtained = 0; ks_obtained <1024; ks_obtained++) some_memory = (char *)malloc(size_to_allocate);
if (some_memory == NULL) ieșire (EXIT_FAILURE);
sprintf (some_memory, "Hello World");
>
megs_obtained ++;
printf ("Acum alocat Megabytesn", megs_obtained);
>
ieșire (EXIT_SUCCESS);
>

De data aceasta, producția, de asemenea abreviată, arată astfel:

$ ./memory3
Acum au alocat 1 megabytes
.
Acum s-au alocat 1535 megaocteți
Acum s-au alocat 1536 megabytes
Out of Memory: Procesul ucis 2365
ucis

Memoria alocată aplicației este controlată de kernel-ul Linux. De fiecare dată când programul solicită memorie, încearcă să scrie în memorie sau să citească din memoria care a fost alocată, kernelul Linux decide cum să se ocupe de această solicitare.

În primul rând, kernel-ul poate utiliza memoria fizică liberă pentru a satisface cererea de alocare de memorie aplicație, dar atunci când memoria fizică este epuizată, kernel-ul începe să utilizeze zona de swap așa-numitele sau swap. În Linux, aceasta este o zonă separată a discului, alocată în timpul instalării sistemului. Dacă sunteți familiarizat cu Windows, funcționarea zonei swap în Linux este un pic asemănător unui fișier swap în Windows. Dar, spre deosebire de sistemul de operare Windows atunci când scrierea de cod nu trebuie să vă faceți griji cu privire la local sau heap globală (heap), sau despre segmentele paginate - Linux kernel organiza totul pentru tine.

Datele se mută de nucleu și un cod între memoria fizică și spațiu de swap, astfel încât la fiecare citire din memorie sau a scrie date în ea pare, în memoria fizică, indiferent de locul unde acestea sunt de fapt în fața încercarea de a le contacta.

Ca urmare, atunci când aplicația are memorie și zona de fizică și de swap sau atunci când aceasta depășește dimensiunea maximă a stivei, kernel-ul va refuza să execute o cerere de alocare suplimentară, pot completa programul și-l descarce.

remarcă

Acest comportament, însoțit de distrugerea procesului, este diferit de comportamentul versiunilor mai vechi de Linux și al multor alte variante UNIX în care funcția malloc sa prăbușit. Este numit distrugerea din cauza lipsei de memorie (din memorie (MOF) ucigaș), și, deși poate părea prea radicală, de fapt, este un compromis rezonabil între un proces rapid și eficient de alocare și necesitatea de a se proteja nucleul epuizarea completă a resurselor, este o problemă serioasă.

Aceasta pare a fi o sursă nelimitată de memorie, cu întreruperea și distrugerea ulterioară a procesului, care în verificarea rezultatului returnat de funcția malloc. nu are sens? Bineînțeles că nu. Una dintre cele mai frecvente probleme din programele C care utilizează memoria dinamică este scrierea în afara blocului alocat. Când se întâmplă acest lucru, este posibil ca programul să nu se termine imediat, dar probabil că veți suprascrie unele dintre datele interne utilizate de rutinele bibliotecii malloc.

Rezultatul obișnuit este prăbușirea apelurilor malloc ulterioare, nu din cauza lipsei de memorie, ci din cauza structurilor de memorie corupte. Asemenea probleme pot fi dificil de urmărit și cu cât programul găsește mai repede o eroare, cu atât este mai mare șansa de a găsi cauza. În capitolul 10 despre depanare și optimizare, vom discuta câteva instrumente care vă pot ajuta să identificați problemele de memorie.







Articole similare

Trimiteți-le prietenilor: