czy new/malloc/mmap alokuje pamięć fizyczną też czy tylko wirtualną od razu przy alokacji?

0

Witam
Pytanie może głupie, ale po zapoznaniu się z modelem przestrzeni adresowej procesu w linuxie to nie wiem.
Do tej pory w przypadku new i malloc myślałem że od razu jest alokowana pamięć wirtualna procesu na stercie oraz od razu też pamięć fizyczna (czyli dla stron w tablicy stron procesu są przypisane jakieś ramki fizyczne od razu po wywołaniu operatora new np. new int [90]). Dla mmap sądziłem że po alokacji jest tylko pamięć wirtualna alokowana i dopiero jak sie odwołujesz pod konkretny indeks to jest przerwanie page faulty i system operacyjny przypisuje jakąś ramkę fizyczną.
Ale teraz już zgłupiałem i być może żyję w błędzie i malloc/new działa tak samo - czyli ramki fizyczne z pamięci RAM są dopiero przypisywane do stron w momencie odwoływania się do poszczególnych indeksów.
Ponadto zastanawiam się co zwracają nam adresy zmiennych lokalnych, zmiennych zarezerwowanych przez new/malloc? To są adresy pamięci wirtualnej, nie fizycznej? Czy z poziomu user spejsa da radę jakoś dowiedzieć się jakie są adresy z pamięci RAM?

0

Działanie malloc jest zależne od implementacji w danej bibliotece standardowej, zwykle ma pod spodem jakiś tam bufor z którego dokonuje alokacji, natomiast ten bufor jest już normalnie alokowany mmapem. Polecam napisanie prostego programu robiącego coś z alokacjami i użycie strace do zaobserwowania co się dzieje, ja np. napisałem teraz program który robi malloc(20000000) i w wyjściu strace mam coś takiego:

mmap(NULL, 20000768, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_ANONYMOUS, -1, 0) = 0x7f27db3ea000
0

Po kolei:

  1. Nie, zawsze alokujesz tylko pamięć wirtualną, dzięki temu aplikacja nie musi się przejmować gdzie fizycznie ta pamięć się znajduje.
  2. To zależy, ale możesz przyjąć, że to pamięć wirtualna
  3. Nie, ze względu na to, że jak masz stronicowanie, to fizyczny adres zmiennej może się zmieniać pomiędzy odwołaniami.
0

ja np. napisałem teraz program który robi malloc(20000000) i w wyjściu strace mam coś takiego:

mmap(NULL, 20000768, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_ANONYMOUS, -1, 0) = 0x7f27db3ea000

Zmień ilość bajtow na 4 i zobacz czy dalej jest mmap

0

Pod Windows (i Visual C++) malloc/new wywołują za każdym razem funkcję systemową HeapAlloc. Czyli microsoftowa biblioteka standardowa C nie ma własnej implementacji sterty, tylko używa systemowej nawet dla najmniejszych alokacji. To wewnątrz HeapAlloc jest obsługa sterty, czyli przydzielanie pamięci pod poszczególne obiekty w ramach większych zaalokowanych wcześniej bloków.
W razie konieczności zaalokowania nowego bloku, HeapAlloc wywołuje VirtualAlloc, która to funkcja alokuje bloki pamięci wirtualnej (ściślej: wywołuje funkcję kernela NtAllocateVirtualMemory która to robi).
Pamięć fizyczna jest alokowana i zerowana dopiero w momencie pierwszego użycia pamięci wirtualnej: pierwsza próba odczytu lub zapisu do bloku pamięci (tzw. strony, zwykle 4 kB) zwróconego przez VirtualAlloc powoduje wyjątek page fault, w ramach którego zaalokowana zostaje pamięć fizyczna i przypisana do danego adresu przestrzeni wirtualnej, po czym program jest wznawiany.

1 użytkowników online, w tym zalogowanych: 0, gości: 1