Jest to właściwie dość proste, gdy zrozumiesz, że opłata zatwierdzenia stanowi tylko potencjalne - ale „gwarantowane dostępne, jeśli chcesz” - wykorzystanie pamięci wirtualnej, podczas gdy „prywatny zestaw roboczy” - który jest zasadniczo pamięcią RAM używaną przez „zatwierdzoną” pamięć - jest faktycznym zastosowaniem, podobnie jak przestrzeń pliku strony. (Ale to nie wszystko z wykorzystania pamięci RAM, ponieważ istnieją inne rzeczy, które używają pamięci RAM).
Załóżmy, że mówimy o systemach 32-bitowych, więc maksymalna wirtualna przestrzeń adresowa dostępna dla każdego procesu wynosi zwykle 2 GiB. (W systemach 64-bitowych nie ma istotnej różnicy w żadnym z poniższych elementów, z tym wyjątkiem, że adresy i rozmiary mogą być większe - znacznie większe).
Załóżmy teraz, że program działający w procesie używa VirtualAlloc (Win32 API) do „zatwierdzenia” 2 MiB pamięci wirtualnej. Jak można się spodziewać, pojawi się to jako dodatkowe 2 MB opłaty zatwierdzenia, a w procesie jest dostępnych o 2 MB mniej bajtów wirtualnej przestrzeni adresowej dla przyszłych przydziałów.
Ale tak naprawdę nie zużyje jeszcze żadnej pamięci fizycznej (RAM)!
Połączenie VirtualAlloc zwróci dzwoniącemu adres początkowy przydzielonego regionu; region będzie gdzieś w zakresie od 0x10000 do 0x7FFEFFFF, tj. około 2 GiB. (Pierwszy i ostatni 64 kB lub 0x10000 szesnastkowy vas w każdym procesie nigdy nie są przypisywane).
Ale znowu - nie ma jeszcze fizycznego wykorzystania 2 MiB pamięci ! Nie w pamięci RAM, nawet w pliku stronicowania. (Istnieje niewielka struktura zwana „deskryptorem adresu wirtualnego”, która opisuje początkową wartość va i długość prywatnego zatwierdzonego regionu).
Więc masz! Opłata za zatwierdzenie wzrosła, ale zużycie pamięci fizycznej nie wzrosło.
Łatwo to zademonstrować za pomocą narzędzia sysinternals testlimit
.
Jakiś czas później, powiedzmy, że program przechowuje coś (tj. Operację zapisu do pamięci) w tym regionie (nieważne gdzie). Pod żadnym regionem nie ma jeszcze fizycznej pamięci, więc taki dostęp spowoduje błąd strony . W odpowiedzi na którą menedżer pamięci systemu operacyjnego, a konkretnie procedura obsługi błędów stron (w skrócie „pager” ... nazywa się MiAccessFault):
- przydziel wcześniej dostępną stronę fizyczną
- skonfiguruj pozycję tabeli stron dla strony wirtualnej, do której uzyskano dostęp, aby powiązać numer strony wirtualnej z nowo przypisanym fizycznym numerem strony
- dodaj stronę fizyczną do prywatnego zestawu roboczego procesu
- i odrzuć błąd strony, powodując ponowienie instrukcji, która spowodowała błąd.
Teraz „zepsułeś” jedną stronę (4 KiB) w procesie. Wykorzystanie pamięci fizycznej odpowiednio wzrośnie, a „dostępna” pamięć RAM zmniejszy się. Opłata za zatwierdzenie nie zmienia się.
Jakiś czas później, jeśli strona nie była przez jakiś czas odsyłana, a zapotrzebowanie na pamięć RAM jest wysokie, może się to zdarzyć:
- system operacyjny usuwa stronę z zestawu roboczego procesu.
- ponieważ został napisany, odkąd został wprowadzony do zestawu roboczego, jest umieszczany na zmodyfikowanej liście stron (w przeciwnym razie przejdzie na listę stron rezerwowych). Wpis tabeli stron nadal odzwierciedla fizyczny numer strony pamięci RAM, ale teraz jego „poprawny” bit jest wyczyszczony, więc przy następnym odwołaniu wystąpi błąd strony
- gdy zmodyfikowana lista stron osiągnie mały próg, zmodyfikowany wątek piszący strony w procesie „System” budzi się i zapisuje zawartość zmodyfikowanych stron w pliku stronicowania (zakładając, że taki masz) i ...
- usuwa te strony ze zmodyfikowanej listy i umieszcza je na liście rezerwowej. Są teraz uważane za część „dostępnej” pamięci RAM; ale na razie wciąż mają swoją oryginalną zawartość z okresu, w którym byli w swoich procesach. Ponownie, opłata zatwierdzenia nie zmienia się, ale zużycie pamięci RAM i prywatny zestaw roboczy procesu spadną.
- Strony na liście rezerwowej można teraz zmienić przeznaczenie , co oznacza, że są używane do czegoś innego - na przykład do usuwania błędów stron z dowolnego procesu w systemie lub używanego przez SuperFetch. Jednak...
- Jeśli proces, który utracił stronę na zmodyfikowanej lub rezerwowej liście, próbuje uzyskać do niej dostęp ponownie, zanim strona fizyczna zostanie zmieniona (tj. Nadal ma swoją oryginalną zawartość), błąd strony zostanie rozwiązany bez odczytu z dysku. Strona jest po prostu umieszczana z powrotem w zestawie roboczym procesu, a pozycja tabeli stron jest „ważna”. To jest przykład błędu strony „miękkiej” lub „taniej”. Mówimy, że listy rezerwowe i zmodyfikowane tworzą ogólnosystemową pamięć podręczną stron, które prawdopodobnie będą wkrótce potrzebne.
Jeśli nie masz pliku stronicowania, kroki od 3 do 5 są zmieniane na:
Strony znajdują się na zmodyfikowanej liście, ponieważ nie ma gdzie napisać ich zawartości.
Strony znajdują się na zmodyfikowanej liście, ponieważ nie ma gdzie napisać ich zawartości.
Strony znajdują się na zmodyfikowanej liście, ponieważ nie ma gdzie napisać ich zawartości.
Krok 6 pozostaje taki sam, ponieważ strony na zmodyfikowanej liście mogą zostać zarzucone z powrotem do procesu, który utracił je jako błąd „miękkiej” strony. Ale jeśli tak się nie stanie, strony będą znajdować się na zmodyfikowanej liście, dopóki proces nie zwolni odpowiedniej pamięci wirtualnej (być może dlatego, że proces się kończy).
Istnieje inne wykorzystanie wirtualnej przestrzeni adresowej i pamięci RAM oprócz prywatnej pamięci zatwierdzonej. Istnieje odwzorowana wirtualna przestrzeń adresowa, dla której magazyn kopii zapasowych jest jakimś określonym plikiem, a nie plikiem strony. Strony zmapowanych waz, które są stronicowane, są odzwierciedlone w użyciu pamięci RAM, ale zmapowana pamięć nie przyczynia się do zatwierdzenia opłaty, ponieważ zmapowany plik zapewnia przechowywanie kopii zapasowych: Każda część zmapowanego regionu, która nie jest w pamięci RAM, jest po prostu przechowywana w plik odwzorowany. Inna różnica polega na tym, że większość mapowań plików może być współużytkowana przez procesy; udostępniona strona, która jest już w pamięci dla jednego procesu, może zostać dodana do innego procesu bez konieczności ponownego przechodzenia na dysk (kolejny błąd strony miękkiej).
I istnieją niestronicowane vas, dla których nie ma sklepu z podkładami, ponieważ zawsze jest rezydentem w pamięci RAM. Przyczynia się to zarówno do zgłaszanego użycia pamięci RAM, jak i do „opłaty zatwierdzenia”.
Wydaje się, że przyczyną może być kompresja. Co zmienia pytanie: Dlaczego limit nie zatwierdza, a nie idzie w górę czy coś takiego? Jaki jest sens kompresji, jeśli nie pomaga w zużyciu pamięci?
Nie. Nie ma to nic wspólnego z kompresją. Kompresja pamięci w systemie Windows odbywa się jako etap pośredni na stronach, które w przeciwnym razie zostałyby zapisane do pliku stronicowania. W efekcie pozwala zmodyfikowanej liście stron zużywać mniej pamięci RAM, aby pomieścić więcej rzeczy, przy pewnym koszcie czasu procesora, ale z dużo większą prędkością niż we / wy pliku strony (nawet na dysku SSD). Ponieważ limit zatwierdzania jest obliczany na podstawie całkowitej pamięci RAM + rozmiaru pliku strony, a nie użycia pamięci RAM + użycia pliku strony, nie wpływa to na limit zatwierdzania. Limit zatwierdzania nie zmienia się w zależności od tego, ile pamięci RAM jest w użyciu ani do czego jest używane.
Kiedy ładowanie się ładuje i Windows zaczyna prosić mnie o zamknięcie rzeczy, przez większość czasu pamięć fizyczna wynosi około 60%. To wydaje się okropnie nieefektywne.
Nie chodzi o to, że Windows jest nieefektywny. To aplikacje, które uruchamiasz. Popełniają o wiele więcej vas, niż faktycznie używają.
Powodem całego mechanizmu „opłaty zatwierdzenia” i „limitu zatwierdzenia” jest to: kiedy wywołuję VirtualAlloc, powinienem sprawdzić wartość zwracaną, aby zobaczyć, czy nie jest ona zerowa. Jeśli wynosi zero, oznacza to, że moja próba alokacji nie powiodła się, prawdopodobnie dlatego, że spowodowałaby, że opłata za zatwierdzenie przekroczyła limit zatwierdzenia. Powinienem zrobić coś rozsądnego, np. Spróbować popełnić mniej lub wyjść z programu czysto.
Jeśli VirtualAlloc zwróci wartość niezerową, tj. Adres, który mówi mi, że system złożył gwarancję - zobowiązanie, jeśli chcesz - że niezależnie od liczby bajtów, o które prosiłem, zaczynając od tego adresu, będzie dostępnych, jeśli zdecyduję się uzyskać do nich dostęp; że jest miejsce, w którym można to wszystko umieścić - albo pamięć RAM, albo plik stronicowania. tzn. nie ma powodu, aby oczekiwać jakiegokolwiek niepowodzenia w dostępie do czegokolwiek w tym regionie. To dobrze, ponieważ nie byłoby rozsądne oczekiwać, że sprawdzę, czy „zadziałało?” przy każdym dostępie do przydzielonego regionu.
Analogia „banku pożyczającego pieniądze”
To trochę jak bank oferujący kredyty, ale wyłącznie gotówka. (To nie jest oczywiście sposób działania prawdziwych banków.)
Załóżmy, że bank zaczyna od gotówki w wysokości miliona dolarów. Ludzie chodzą do banku i proszą o linie kredytowe w różnych kwotach. Powiedzmy, że bank zatwierdza mnie na linię kredytową w wysokości 100 000 USD (tworzę prywatny region, w którym przyznano środki); to nie znaczy, że jakakolwiek gotówka opuściła skarbiec. Jeśli później rzeczywiście wezmę pożyczkę na, powiedzmy, 20 000 USD (uzyskuję dostęp do podzbioru regionu), spowoduje to usunięcie gotówki z banku.
Ale niezależnie od tego, czy zaciągnę jakieś pożyczki, czy nie, fakt, że zostałem zatwierdzony na maksymalnie 100 000 USD, oznacza, że bank może następnie zatwierdzić kolejne linie kredytowe o łącznej wartości 900 000 USD dla wszystkich swoich klientów. Bank nie zatwierdzi kredyt w nadmiarze swoich rezerw pieniężnych (czyli nie będzie overcommitu je), ponieważ oznaczałoby to bank może trzeba włączyć wcześniej zatwierdzony kredytobiorcy z dala kiedy później pokazać się z zamiarem wykupienia ich kredyt . Byłoby to bardzo złe, ponieważ bank już zobowiązał się do udzielenia tych pożyczek, a reputacja banku gwałtownie spadłaby.
Tak, jest to „nieefektywne” pod względem wykorzystania tej gotówki przez bank. Im większa jest różnica między liniami kredytowymi, na które klienci są zatwierdzeni, a kwotami, które faktycznie pożyczają, tym mniej jest to efektywne. Ale ta nieefektywność nie jest winą banku; to „wina” klientów za to, że proszą o tak wysokie linie kredytowe, a jedynie zaciągają niewielkie pożyczki.
Model biznesowy banku polega na tym, że po prostu nie może odrzucić wcześniej zatwierdzonego pożyczkobiorcy, kiedy pojawia się, aby uzyskać pożyczkę - byłoby to dla klienta „śmiertelne”. Dlatego bank uważnie śledzi, ile funduszy pożyczkowych zostało „zaangażowanych”.
Podejrzewam, że rozszerzenie pliku strony lub dodanie innego byłoby jak wyjście banku i zdobycie większej ilości gotówki i dodanie jej do funduszu pożyczkowego.
Jeśli chcesz zamodelować zmapowaną i niestronicowaną pamięć w tej analogii ... niestronicowana jest jak mała pożyczka, którą musisz wyjąć i trzymać z daleka po otwarciu konta. (Niestronicowe struktury, które definiują każdy nowy proces.) Odwzorowana pamięć jest jak zabranie ze sobą własnej gotówki (pliku, który jest mapowany) i zdeponowanie jej w banku, a następnie wyjęcie tylko jej części na raz (stronicowanie). Dlaczego by nie umieścić wszystkich stron jednocześnie? Nie wiem, może nie masz miejsca w portfelu na te wszystkie pieniądze. :) Nie wpływa to na zdolność innych osób do pożyczania pieniędzy, ponieważ wpłacone środki pieniężne znajdują się na Twoim koncie, a nie w ogólnym funduszu pożyczkowym. Ta analogia zaczyna się tam załamywać, zwłaszcza gdy zaczynamy myśleć o pamięci wspólnej, więc nie przesadzaj.
Powrót do systemu operacyjnego Windows: fakt, że większość pamięci RAM jest „dostępna”, nie ma nic wspólnego z opłatą zatwierdzania i limitem zatwierdzania. Jeśli zbliżasz się do limitu zatwierdzeń, oznacza to, że system operacyjny już zatwierdził - tj. Obiecał udostępnić, gdy zostaniesz o to poproszony - tyle pamięci. Nie musi być jeszcze w użyciu, aby można było wprowadzić limit.
Czy mogę zrezygnować ze sztucznego pompowania pliku strony do poziomów, w których mój głodny SSD jest źle wyposażony do obsługi, tak aby faktycznie móc efektywnie wykorzystać moją pamięć fizyczną? (Lub nawet jeśli nie byłby tak pełny. To znaczy, chciałbym unikać sugestii typu „Do X / Y / Z do pliku strony”.)
Przykro mi, ale jeśli napotykasz limit zatwierdzeń, możesz zrobić tylko trzy rzeczy:
- Zwiększ swoją pamięć RAM.
- Zwiększ rozmiar pliku strony.
- Uruchamiaj mniej rzeczy za jednym razem.
Re opcja 2: Możesz umieścić drugi plik stronicowania na dysku twardym. Jeśli aplikacje nie wykorzystują całej zajętej pamięci - która najwyraźniej tak nie jest, ponieważ widzisz tak dużo wolnej pamięci RAM - tak naprawdę nie będziesz mieć dostępu do tego pliku strony, więc umieszczenie go na dysku twardym nie spowoduje zaszkodzić wydajności. Jeśli powolność dysku twardego nadal Ci przeszkadza, inną opcją jest zdobycie małego, a zatem taniego drugiego dysku SSD i umieszczenie na nim drugiego pliku stronicowania. Jednym z „showstopperów” byłby laptop bez możliwości dodania drugiego „nieusuwalnego” napędu. (Windows nie pozwoli ci umieszczać plików stronic na dyskach wymiennych, jak wszystko połączone z USB.)
Oto kolejna odpowiedź, którą napisałem, która wyjaśnia wszystko z innego kierunku.
ps: Pytałeś o Windows 10, ale powinienem powiedzieć, że działa on tak samo w każdej wersji rodziny NT, z powrotem do NT 3.1, a także w wersjach wstępnych. To, co najprawdopodobniej uległo zmianie, to domyślne ustawienie rozmiaru pliku stronicowania w Windows, z 1,5x lub 1x RAM do znacznie mniejszego. Uważam, że to był błąd.