This is an old revision of the document!


Curs 06 - Memoria virtuală

  • Suport curs
    • Operating Systems Concepts Essentials
      • Capitolul 8 - Virtual Memory
    • Modern Operating Systems
      • Capitolul 4 - Memory Management
        • Secțiunile 4.4, 4.5

Demo-uri

Pentru parcurgerea demo-urilor, folosim arhiva aferentă. Demo-urile rulează pe Linux. Descărcăm arhiva folosind comanda

wget http://elf.cs.pub.ro/so/res/cursuri/curs-06-demo.zip

și apoi decomprimăm arhiva

unzip curs-06-demo.zip

și accesăm directorul rezultat în urma decomprimării

cd curs-06-demo/

Acum putem parcurge secțiunile cu demo-uri de mai jos.

Alocarea variabilelor într-un executabil

Dorim să investigăm modul în care se alocă variabilele într-un executabil. Pentru aceasta accesăm subdirectorul exec-vars/; urmărim conținutul fișierului exec-vars.c. În acest fișier definim/alocăm variabile în diverse forme: dinamic, static, global. Vrem să vedem cum sunt acestea alocate în executabil și în proces.

Compilăm programul folosind make.

Investigăm zonele de memorie din executabil în care sunt salvate variabilele, folosind comanda

objdump -t addr-space | grep var

De ce apar doar unele variabile?

Răspuns

Răspuns

Pentru variabilele alocate dinamic (pe stivă, heap) se alocă la runtime, adică în momentul în care procesul rulează. Executabilul nu are legătură cu datele alocate la runtime.

Ce semnfică l și g în output-ul obținut?

Răspuns

Răspuns

Arată că variabilele respective sunt simboluri globale (g - la nivelul întregului modul) sau locale (l - locale unei funcții).

Pentru a afișa conținutul zonei .rodata folosind comanda

readelf -x .rodata addr-space

Secțiunea .rodata conține variabile read-only, în cazul de față literalul rulz. Literalii și constantele se stocează în secțiunea .rodata a unui executabil.

Investigarea mapării folosind pmap

Vrem să vizualizăm spațiul virtual de adrese al unui proces. Pentru aceasta, accesăm subdirectorul pmap; urmărim conținutul fișierului pmap.c; facem mapări (folosind apelul mmap) folosind diverse flag-uri.

Compilăm programul folosind make și apoi îl rulăm:

./pmap

Într-o altă consolă urmărim schimbările din spațiul virtual de adrese al procesului creat folosind comanda

watch -d pmap $(pidof pmap)

Comanda de mai sus urmărește spațiul virtual de adrese. Ca să generăm schimbări în spațiul virtual de adrese, apăsăm ENTER în consola în care rulează programul pentru a continua pașii din cod.

Urmărim modificările care apar în urma diferitelor tipuri de mapare din cod. Observăm că se mapează câte o singură pagină; la fiecare operație de mapare spațiul total crește cu 4K, iar la fiecare operație de demapare spațiul total scade cu 4K. Observăm că în cazul mapării partajate permisiunile sunt rw-s; s înseamnă shared. Tot în cazul memoriei partajate apare mapat dispozitivul /dev/zero, unul dintre modurile uzuale de a face mapare partajată.

De ce unele biblioteci sunt mapate cu permisiuni de scriere?

Răspuns

Răspuns

Bibliotecile au mai multe secțiuni, similar unui executabil, mapate cu permisiunile corespunzătoare. Secțiunea de cod/text este mapată cu permisiuni de citire și execuție (r-x), cea de date este mapată cu permisiuni de citire și scriere (rw-) iar cea de date read-only este mapată cu permisiuni doar de citire (r–).

  1. Alocarea de memorie virtuală
    • Intrați în directorul 3-allocation/.
    • Consultați fișierul allocation.c.
    • Compilați sursele folosind comanda make.
    • Deschideți o consolă nouă.
    • Într-o consolă rulați executabilul aferent:
      ./allocation
    • Într-o altă consolă vizualizați dimensiunea spațiului fizic ocupat și a a spatiului virtual ocupat, folosind comanda:
      watch -n 1 ps -o pid,rss,vsz,cmd -p $(pidof allocation)
    • Observați cum crește dimensiunea spațiului fizic și a spatiului virtual în cazul folosirii malloc și doar a spațiului virtual folosind mmap.
      • Cum explicați acest comportament?
    • Rulați executabilul prin strace:
      strace ./allocation
      • Ce apel de sistem invocă funcția malloc?
      • Dar funcția mmap?
      • De ce, la 1024 de apeluri ale funcției malloc sunt mai puține apeluri de sistem?
    • Actualizați codul astfel încât malloc să aloce, la fel ca și mmap calupuri de 1MB de memorie.
    • Compilați noua sursă folosind comanda make.
    • Rulați executabilul într-o consolă și comanda de vizualizare în altă consolă.
      • Ce observați?
      • Cum vă explicați acest comportament?
    • Rulați executabilul nou prin strace.
      • Ce apel de sistem invocă acum funcția malloc?
      • Comparați apelul de sistem (și argumentele acestuia) invocat acum de malloc cu apelul de sistem și argumentele acestuia invocate de mmap.
  2. Paginare la cerere (demand paging)
    • Intrați în directorul 4-demand-paging/.
    • Consultați fișierul demand-paging.c.
    • Compilați sursele folosind comanda make.
    • Deschideți o consolă nouă.
    • Într-o consolă rulați executabilul aferent:
      ./demand-paging
    • Într-o altă consolă vizualizați dimensiunea spațiului fizic ocupat și a a spatiului virtual ocupat, folosind comanda:
      watch -n 1 ps -o pid,rss,vsz,cmd -p $(pidof demand-paging)
    • Observați cum crește dimensiunea spațiului spatiului virtual fără a crește dimensiunea spațiului fizic în prima parte.
      • Observați cum crește dimensiunea spațiului fizic în a doua parte (fără a crește dimensiunea spațiului virtual).
    • Într-o consolă rulați executabilul aferent:
      ./demand-paging
    • Într-o altă consolă vizualizați numărul de page fault-uri generate de program (min_flt este coloana de interes, maj_flt este pentru interacțiuni cu discul – swapping):
      watch -n 1 ps -o pid,min_flt,maj_flt,cmd -p $(pidof demand-paging)
    • Observați cum nu există page fault-uri în prima pare a rulării programului.
      • Observați cum există page fault-uri în a doua parte a rulării programului.
      • Câte page fault-uri sunt generate la o “trecere prin chunk”? De ce?
  3. Page-Faulturi
    • Intrați în directorul 5-fork-faults/.
    • Consultați fișierului fork-faults.c.
    • Câte page-fault-uri credeți că se realizează la rulare?
    • Compilați fișierul.
    • Rulați programul fork-faults.
    • Folosiți ENTER pentru a continua programul, dar după rularea pidstat (vedeți mai jos).
    • Pe un alt terminal sau tab de terminal folosiți utilitarul pidstat din pachetul sysstat care permite monitorizarea page fault-urilor unui proces (prin intermediul argumentului -r).
      • Dacă nu merge comanda pidstat trebuie să instalați pachetul sysstat folosind comanda:
        apt-get install sysstat
    • Folosiți comanda
      pidstat -r -T ALL -p $(pidof fork-faults) 5 100

      pentru a urmări page fault-urile.

      • Comanda de mai sus vă afișează câte un mesaj la fiecare 5 secunde. Sincronizați apăsarea tastei ENTER cu afișajul comenzii pidstat.
    • Urmăriți evoluția numărului de page fault-uri pentru cele două procese: părinte și copil.
      • Page fault-urile care apar în cazul unui copy-on-write în procesul copil vor fi vizibile ulterior și în procesul părinte.
so/cursuri/curs-06.1395516054.txt.gz · Last modified: 2014/03/22 21:20 by razvan.deaconescu
CC Attribution-Share Alike 3.0 Unported
www.chimeric.de Valid CSS Driven by DokuWiki do yourself a favour and use a real browser - get firefox!! Recent changes RSS feed Valid XHTML 1.0