1 / 50

Sistemsko programiranje

Sistemsko programiranje. III. poglavlje Upravljanje memorijom, Memorijski mapirane datoteke i DLLovi. Ciljevi. Nakon svladavanja ovog poglavlja trebali bi znati: Opisati arhitekturu upravljanja memorijom kod Windowsa i ulogu heapova i memorijski mapiranih datoteka

doli
Download Presentation

Sistemsko programiranje

An Image/Link below is provided (as is) to download presentation Download Policy: Content on the Website is provided to you AS IS for your information and personal use and may not be sold / licensed / shared on other websites without getting consent from its author. Content is provided to you AS IS for your information and personal use only. Download presentation by click this link. While downloading, if for some reason you are not able to download a presentation, the publisher may have deleted the file from their server. During download, if you can't get a presentation, the file might be deleted by the publisher.

E N D

Presentation Transcript


  1. Sistemsko programiranje III. poglavlje Upravljanje memorijom, Memorijski mapirane datoteke i DLLovi

  2. Ciljevi • Nakon svladavanja ovog poglavlja trebali bi znati: • Opisati arhitekturu upravljanja memorijom kod Windowsa i ulogu heapova i memorijski mapiranih datoteka • Koristiti višestruke neovisne heapove u aplikacijama koje traže dinamičko upravljanje memorijom • Odgovarati na greške prilikom zauzimanja (alokacije) memorije • Koristiti memorijski mapirane datoteke • Odrediti kada treba koristiti neovisne heapove a kada memorijski mapirane datoteke, i opisati prednosti i nedostatke jednog i drugog • Opisati Windows dinamičke biblioteke - dynamic link libraries (DLL) • Opisati razliku između statičkog, implicitnog i eksplicitnog linkanja (povezivanja), te opisati prednosti i nedostatke svakog od njih • Koristiti DLLove za učitavanje različitih implementacija iste funkcije

  3. Pregled poglavlja (1/2) 32-bitni operacijski sustav, pokazivači su 4-byte-ni objekti Win64 nam omogućavaju 64-bitne pokazivače Procesi imaju privatni 4GB virtualni adresni prostor • Pola (2GB) pripada procesu • Ostatak je zauzet za podatke koji se dijele i za sam kod • Win64 uvećava VA prostor; mnoge aplikacije to traže Programi mogu kreirati neovisne memorijske “heap”-ove Procesi mogu mapirati datoteke u memoriju • Procesi mogu dijeliti memoriju preko mapirane datoteke • Brzo i efikasno za različite načine procesiranja datoteka

  4. Pregled poglavlja (2/2) • DLLovi i monolitni programi • Skupljanje cjelokupnog izvornog koda, uključujući često korištene skupine kao što su korisničke funkcije • Stavljanje cijelog izvornog koda u jedan projekt • Neučinkovitost • Prevođenje istog koda u svim projektima • Sve datoteke za izvođenje uključuju isti objektni kod • Nepotrebni gubitak prostora na disku i fizičke memorije prilikom izvođenja • Složenost održavanja ako se zajednički/djeljeni kod promjeni

  5. Dnevni red • 1. dio Upravljanje memorijom i heapovi • 2. dio Memorijski mapirane datoteke • 3. dio Dynamic Link Libraries (DLL)

  6. 1. dio Upravljanje memorijom i heapovi

  7. Arhitektura upravljanja memorijom Windows Program C library: malloc, free Heap API: HeapCreate, HeapDestroy, HeapAlloc, HeapFree MMF API: CreateFileMapping, CreateViewOfFile Virtual Memory API Windows Jezgra (Kernel) zajedno s Upravljanjem virtualnom memorijom (Virtual Memory Manager) Disk & Datotečni sustav (File system) Fizička memorija (RAM)

  8. Heapovi (1/2) • Memorijska polja (pools of memory) unutar virtualnog adresnog prostora procesa (heap = hrv. hrpa) • Svaki proces ima svoj preddefinirani (default) procesni heap • Proces može imati više od jednog heapa. Prednosti razdvajanja heapova uključuju: • Pravednost (unutar niti i samog korištenja) • Učinkovitost zauzimanja (blokovi fiksne veličine u svakom heapu) • Učinkovitost oslobađanja (može se osloboditi čitava struktura podataka unutar jednog funkcijskog poziva) • Lokalnost kod adresiranja

  9. Heapovi (2/2) Svaki proces ima svoj procesni heap Svaki heap ima svoj handle Programer može koristiti procesni heap kako bi kreirao nove heapove HANDLE GetProcessHeap (VOID) Vraća: Handle od procesnog heapa; NULL u slučaju greške

  10. Upravljanje memorijom kod višestrukih heapova Program Virtualni adresni prostor nije zauzeto ProcHeap = GetProcessHeap ( ); pRoot = HeapAlloc (ProcHeap); Proces Heap · · · nije zauzeto RecHeap = HeapCreate ( ); NodeHeap = HeapCreate ( ); Record · · · RecHeap Record while ( ) { pRec = HeapAlloc (RecHeap); pNode = HeapAlloc (NodeHeap); · · · } Record nije zauzeto Node · · · NodeHeap Node HeapFree (RecHeap, 0, pRec); HeapFree (NodeHeap, 0, pNode); HeapDestroy (RecHeap); HeapDestroy (NodeHeap); Node nije zauzeto

  11. Upravljanje heapom (1/3) HANDLE HeapCreate (DWORD flOptions, DWORD dwInitialSize, DWORD dwMaximumSize) Vraća: handle heapa ili NULL kod greške dwMaximumSize — Koliko veliki heap može postati • 0 — “rastući heap”; nema fiksiranog ograničenja • nije nula — “ne-rastući heap” • Cijeli blok je zauzet iz virtualnog adresnog prostora • Ali samo inicijalna veličina je predana straničnoj datoteci

  12. Upravljanje heapom (2/3) flOptions jest kombinacija dvije zastavice: • HEAP_GENERATE_EXCEPTIONS • HEAP_NO_SERIALIZE Kod generiranja iznimki možemo izbjeći ekspicitno testiranje nakon svakog poziva funkcije koja upravlja heapom

  13. Upravljanje heapom (3/3) BOOL HeapDestroy (HANDLE hHeap) • hHeap — heap napravljen koristeći HeapCreate • Nikad ne uništavati procesni heap (dobiven koristeći GetProcessHeap) • Prednosti korištenja HeapDestroy: • Nije potrebno obilaziti kroz sve veze nekih struktura podataka • Nije potrebno oslobađati memoriju za svaki pojedinačni član strukture podataka, što nekad može biti vremenski zahtjevno

  14. Upravljanje memorijom heapa (1/4) LPVOID HeapAlloc (HANDLE hHeap, DWORD dwFlags, DWORD dwBytes) Vraća: Pokazivač na blok zauzete memorije (veličine dwBytes) ili NULL ako ne uspije (osim ako nije specifirano generiranje iznimki) hHeap — Handle od procesnog heapa dobivenog s GetProcessHeap ili našeg kreiranog heapa dobivenog s HeapCreate dwFlags — Kombinacija sljedećih zastavica: • HEAP_GENERATE_EXCEPTIONS • HEAP_NO_SERIALIZE • HEAP_ZERO_MEMORY — Zauzeta memorija postavlja se na nulu (ako stavimo ovo, onda izvođenje funkcije traje “malo” duže)

  15. Upravljanje memorijom heapa (2/4) BOOL HeapFree (HANDLE hHeap, DWORD dwFlags, LPVOID lpMem) dwFlags — Treba biti nula (ili HEAP_NO_SERIALIZE) lpMem — Treba imati vrijednost koju vraća funkcija HeapAlloc ili HeapReAlloc hHeap — Treba biti heap iz kojeg je zauzet lpMem

  16. Upravljanje memorijom heapa (3/4) LPVOID HeapReAlloc (HANDLE hHeap, DWORD dwFlags, LPVOID lpMem, DWORD dwBytes) Vraća: Pokazivač na blok memorije koji će biti nanovo zauzet. Kod greške vraća se NULL ili se pojavljuje iznimka. dwFlags — Neke osnovne kontrolne opcije: • HEAP_GENERATE_EXCEPTIONS i HEAP_NO_SERIALIZE • HEAP_ZERO_MEMORY — Samo novo-zauzeta memorija je incijalizirana • HEAP_REALLOC_IN_PLACE_ONLY — Ne treba micati blok lpMem — Postojeći blok u heapu hHeap za koji treba zauzeti memoriju ponovno dwByte — Nova veličina bloka

  17. Upravljanje memorijom heapa (4/4) DWORD HeapSize (HANDLE hHeap, DWORD dwFlags, LPVOID lpMem) Vraća: Veličina bloka ili nula prilikom greške.

  18. Zastavice kod heapova HEAP_NO_SERIALIZE • Postoji u HeapCreate, HeapAlloc, i drugim funkcijama • Dobitak pri izvedbi (testovi pokazuju oko 15%) jer funkcija ne omogućava međusobno isključivanje niti koje pristupaju heapu • Može se sigurno koristiti ako (ALI, TREBA BITI OPREZAN): • Proces koristi samo jednu nit • Svaka nit ima svoj heap(ove) kojem(kojima) druge niti ne mogu pristupati • Se napravi sopstveni mehanizam za međusobno isključivanje koji će onemogućiti konkurentni pristup heapu od strane pojedinih niti. • Se koristi HeapLock i HeapUnlock HEAP_GENERATE_EXCEPTIONS • Omogućava da se izbjegne testiranje grešaka nakon svakog pokušaja zauzimanja (alokacije) memorije

  19. Druge funkcije za heap • HeapValidate • Određuje da li je heap oštećen • HeapCompact • Sažima povezane slobodne blokove; vraća veličinu u byte-ima • HeapWalk • Pobrojava sve blokove zauzete unutar heapa

  20. 2. dio Memorijski mapirane datoteke

  21. O mapiranju (prslikavanju) datoteka • Mapiranje datoteka jest povezivanje sadržaja datoteke s dijelom virtalnog adresnog prostora procesa • Prikaz datoteke (file view) jeste dio virtualnog adresnog prostora koji proces koristi da pristupi sadržaju datoteke • Objekt koji je mapirana datoteka se može sastojati od cijele ili samo dijela datoteke • Mapiranje datoteka omogućava dvije važne prednosti: - Dijeljenje memorije - Brži i lakši pristup datoteci

  22. Memorijski mapirane datoteke Prednosti mapiranja (preslikavanja) prostora virtualne memorije direktno u obične datoteke, radije nego u datoteku za straničenje: • Nikada ne treba raditi direktni datotečni I/O • Strukture podataka koje kreirate sačuvane unutar datoteke • Mogu se koristiti algoritmi koji se koriste unutar memorije (procesiranje stringova, sortiranja, pretraživanja) za procesiranje podataka iako datoteka može biti puno veća nego što je ukupna fizička memorija • Nema potrebe za upravljanjem spremnicima (bufferima) i podacima datoteke koje spremnici sadrže • Višestruki procesi mogu dijeliti memoriju (to je jedini način), a prikazi datoteke bit će koherentni (sukladni) • Nema potrebe da se zauzima prostor u datoteci za straničenje

  23. Adresni prostor procesa mapiran u datoteku Program Datoteka fH = CreateFile ( ); mH = CreateFileMapping (fH); · · · while ( ) { pRecA = MapViewOfFile (mH); pRecB = MapViewOfFile (mH); pRecB -> Data = pRecA -> Data; · · · UnmapViewOfFile (pRecA); UnmapViewOfFile (pRecB); } Adresni prostor procesa CloseHandle (mH); CloseHandle (fH);

  24. Objekti mapirane datoteke (1/4) HANDLE CreateFileMapping (HANDLE hFile, LPSECURITY_ATTRIBUTES lpsa, DWORD dwProtect, DWORD dwMaximumSizeHigh, DWORD dwMaximumSizeLow, LPCTSTR lpMapName) Vraća: Handle mapirane (preslikane) datoetke ili NULL

  25. Objekti mapirane datoteke (2/4) Parametri • hFile — handle otvorene datoteke; zastavice zaštite kompatibilne s dwProtect • LPSECURITY_ATTRIBUTES — NULL za sada • dwProtect — Kako se može pristupiti mapiranoj datoteci: • PAGE_READONLY — Stranice u mapiranom području su samo za čitanje • PAGE_READWRITE — Puni pristup ako i hFile ima obadva GENERIC_READ i GENERIC_WRITE pristup • PAGE_WRITECOPY — Kada se napravi neka promjena u mapiranoj memoriji, kopija će biti zapisana u datoteku za straničenje

  26. Objekti mapirane datoteke (3/4) • dwMaximumSizeHigh i dwMaximumSizeLow — Određuju veličinu mapiranog objekta; 0 za trenutnu veličinu datoteke. Datoteka će biti proširena ako je tekuća veličina datoteke manja od veličine mapiranog objekta (tj. preslika). • lpMapName — Imenuje mapriani objekt, s time dopuštajući drugim procesima da dijele isti taj objekt

  27. Objekti mapirane datoteke (4/4) Handle na mapiranu datoteku može se dobiti isto tako ako zadamo već postojeće ime mapiranog objekta HANDLE OpenFileMapping (DWORD dwDesiredAccess, BOOL bInheritHandle, LPCTSTR lpNameP) Vraća: Handle mapirane datoteke ili NULL CloseHandle uništava handle mapriane datoeke (kao i handle-ove druge vrste)

  28. Mapiranje adresnog prostora procesa (1/3) LPVOID MapViewOfFile (HANDLE hMapObject, DWORD dwAccess, DWORD dwOffsetHigh, DWORD dwOffsetLow, DWORD cbMap) Vraća: Početnu adresu bloka (file view) ili NULL kod greške hMapObject — Identificira objekt mapirane datoteke (handle) dwAccess — Mora biti kompatibilan s pristpom mapiranom objektu: • FILE_MAP_WRITE • FILE_MAP_READ • FILE_MAP_ALL_ACCESS

  29. Mapiranje adresnog prostora procesa (2/3) dwOffsetHigh i dwOffsetLow • Početna lokacija područja mapirane datoteke • Mora biti višekratnik od 64K • Nula ako se mapira od početka datoteke cbMap — Veličina u byte-ovima mapiranog područja • Nula upućuje na cijelu datotekuPrimjedba: Veličina mape (preslika) je ograničena na 32-bitne adrese (Win64??)

  30. Mapiranje adresnog prostora procesa (3/3) MapViewOfFileEx je slična, ali se može “predložiti” adresa BOOL UnmapViewOfFile (LPVOID lpBaseAddress) • Da oslobodimo pregled datoteke (file views)

  31. Ograničenja mapiranja datoteka • Nepodudaranje s Windows 64-bitnim datotečnim sustavom i 32-bitnim memorijskim adresiranjem (Win64 više nema ovakvih problema) • Sa velikim datotekama (većim od 4GB) ne može se mapirati sve unutar virtualnog memorijskog prostora (Win64 više nema ovakvih problema) • Podatkovni prostor procesa je ograničen na 2GB (Win64 više nema ovakvih problema) • Ne može se koristiti svih 2GB; kontinuirani blokovi u tom prostoru bit će manji (Ako imamo dovoljno memorije, Win64 više nema ovakvih problema) • Kada radimo s velikim datotekama, moramo napisati programski kod koji će se brinuti o mapiranju i oslobađanju (unmap) područja datoteke kako koje zatrebamo (Ako imamo dovoljno memorije, Win64 više nema ovakvih problema)

  32. Bazirani pokazivači (1/2) Bazirani pokazivači (based pointers) Ako se koriste pokazivači unutar područja mapirane datoteke onda oni moraju biti tipa _based • Konvencionalni pokazivači imaju vrijednost virtualne adrese • Ova bazna adresa će biti zasigurno drugačija kada naredni put mapiramo datoteku, ili formiramo novi pregled datoteke jednog te istog područja • Pokazivač mora biti “baziran” na osnovu adrese pregleda datoteke (file view-a)

  33. Bazirani pokazivači (2/2) int *pi; int __based(pi) *bpi, i; ... pi = MapViewOfFile (...); *pi = 3; bpi = pi; i = *bpi; ...

  34. 3. dio Dynamic Link Libraries (DLL)

  35. Statičke biblioteke • Prednosti • Pojednostavljuje izgradnju projekta • Mane • Stvari vezane za disk i memoriju • Održavanje zahtjeva ponovno linkanje i redistribuciju • Različiti programi mogu koristiti različite verzije biblioteke • Programi ne mogu koristiti alternativne korisničke implementacije za različite situacije

  36. Dynamic link libraries (1/4) • Dinamički povezive biblioteke - DLL-ovi rješavaju mnoge probleme jako jednostavno i spretno • Funkcije biblioteke se povezuju (linkaju) pri: • Učitavanju programa — implicitno povezivanje • Izvođenju programa — eksplicitno povezivanje • Slika programa može biti puno manja • Ne uključuje funkcije iz biblioteke • Više programa može koristiti jedan DLL • Samo jedna kopija će biti učitana u memoriju • Svi programi preslikavaju svoj adresni prostor za DLL kod • Svaka nit će imati svoju kopiju ne dijeljenog prostora na stogu

  37. Dynamic link libraries (2/4) • Nove verzije ili alternativne implementacije: • Omogućavaju se nove verzije DLL-ova • Svi programi mogu koristiti novu verziju bez modifikacija • Eksplicitno povezivanje: • Program odlučuje dok se izvršava koju verziju biblioteke će koristiti • Različite biblioteke mogu biti alternativne implementacije jedne te iste funkcije • Mogu se izvoditi totalno različite zadaće • Isto kao što rade različiti programi • Biblioteka će se izvoditi u istom procesu i niti kao i program koji ju poziva

  38. Dynamic link libraries (3/4) • DLL-ovi se koriste u skoro svim operacijskim sustavima • Uključujući UNIX i prastare Windows 3.1 • Windows (sve verzije) koriste DLL-ove da implementiraju OS međusklopovlje (interface), pored ostalih stvari • Windows 3.1 DLL-ovi se izvode u istom adresnom prostoru za sve procese • Windows DLL-ovi se izvode u virtualnom adresnom prostoru svakog procesa

  39. Dynamic link libraries (4/4) • Više Windows procesa mogu dijeliti DLL kod • Kod, kada se pozove, izvodi se kao dio pozivajućeg procesa i niti • Biblioteka može koristiti resurse pozivajućeg procesa (datotečne handle-ove, ...) • Koristi se stog pozivajuće niti • DLL-ovi moraju biti zaštićeni unutar niti “thread-safe” • DLL-ovi mogu eksportirati varijable kao i funkcijske ulazne točke

  40. Implicitno povezivanje (1/2) • Implicitno, ili prilikom učitavanja, povezivanje je lakša od dviju tehnika • Koraci: • Prikupiti i napraviti izvorni kod funkcija kao DLL • Proces pravljenja (Build) projekta stvara .LIB datoteku • Staviti .LIB u projektni ‘library’ direktorij • Proces pravljenja također stvara .DLL datoteku

  41. Implicitno povezivanje (2/2) • Sadrži aktuelnu izvršnu sliku • Stavljena je u isti direktorij kao i aplikacija koja ju koristi • Tekući radni direktorij je sekundarna lokacija • Nakon toga sistemski direktorij, Windows direktorij, PATH • Program učitava DLL tijekom svoje incijalizacije • Mora se “eksportirati” funkcijsko povezivanje unutar DLL izvornog koda

  42. Eksportiranje i importiranje (1/3) DLL ulazna točka mora biti deklarirana • Microsoft C, koristi _declspec (dllexport) modifikator smještaja: _declspec (dllexport) DWORD MyFunction (...); Program koji poziva funkciju, deklarira ju kao funkciju koju treba importirati • Koristi se _declspec (dllimport) modifikator smještaja

  43. Eksportiranje i importiranje (2/3) • Standardna tehnika unutar ‘include’ datoteke • Treba koristiti preprocesorsku varijablu kao što je primjerice “MYPROJ_EXPORTS“ • “MYPROJ” je ime vašeg projekta #ifdef MYPROJ_EXPORTS #define LIBSPEC _declspec (dllexport) #else #define LIBSPEC _declspec (dllimport) #endif LIBSPEC DWORD MyFunction (...);

  44. Eksportiranje i importiranje (3/3) • Unutar DLL projekta definiramo MYPROJ_EXPORTS • Aplikacija koja poziva ostavlja MYPROJ_EXPORTS nedefiniran • Mogu se eksportirati i importirati i varijable isto kao funkcijske ulazne točke

  45. Eksplicitno povezivanje (1/4) • Eksplicitno (prilikom izvođenja) povezivanje zahtjeva: • Program može učitati DLL — LoadLibrary • Traženje adrese ulazne točke funkcije — GetProcAddress • Prevođenje (cast) adresnog pokazivača na tip funkcije • Pozivanje funkcije koristeći pokazivač • Opcionalno oslobađanje biblioteke — FreeLibrary • Primjedba: Funkcija nije deklarirana u programu koji poziva DLL; zato se definira varijabla kao pokazivač na funkciju • Zbog toga, nije potrebna .LIB datoteka prilikom povezivanja (znači linkanja programa koji koristi DLL)

  46. Eksplicitno povezivanje (2/4) HINSTANCE LoadLibrary (LPCTSTR lpLibFileName) Vraćeni handle je NULL ako dođe do greške HINSTANCE, radije nego konvencionalni HANDLE • Sadrži drugačiju informaciju

  47. Eksplicitno povezivanje (3/4) BOOL FreeLibrary (HINSTANCE hLibModule) Gotovi smo s upotrebom biblioteke ili želimo neku drugu verziju LoadLibraryEx je slična funkcija • Nekoliko zastavica koje određuju alternativne putanje traženja biblioteke te učitavanje biblioteke kao datoteke s podacima

  48. Eksplicitno povezivanje (4/4) Za dobivanje ulazne točke funkcije • FARPROC GetProcAddress (HMODULE hModule, LPCSTR lpProcName) hModule jest primjerak (instance) dobiven od LoadLibrary • Ili GetModuleHandle (ovu funkciju ovdje ne opisujemo) lpProcName jest ime ulazne točke funkcije • Ne može biti Unicode NULL se vraća u slučaju greške FARPROC, nešto kao “dugački pokazivač” - zastarjelo (vuče korjene još od 16-bitnih pokazivača)

  49. Učitavanje DLL-a BOOL (*MojaFunk)(LPCTSTR, LPCTSTR, BOOL); FARPROC pMF; /* Učitaj dinamičku biblioteku imena moja.dll */ hDLL = LoadLibrary (“moja.dll”); /* Nađi adresu ulazne točke funkcije */ pMF = GetProcAddress (hDLL, ”MojaFunk"); /* Prevedi u pokazivač na funkciju */ MojaFunk = (BOOL (*)(LPCTSTR, LPCTSTR, BOOL)) pMF; /* Pozovi funkciju */ MojaFunk(“prvi string”, “drugi string”, FALSE); /* Oslobodi biblioteku (nakon ovog više ne smijemo pozivati MojaFunk(..) */ FreeLibrary( hDLL );

More Related