Pytanie to wynika z następujących regularnie obserwowanych zjawisk, dla których chciałbym znaleźć wyjaśnienie:
- Bieżące zatwierdzanie jest regularnie wyższe niż użycie fizyczne + rozmiar pliku strony. O co chodzi? Czy nie powinno to być niemożliwe? [Wydaje się, że może to być spowodowane kompresją. 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?]
- Czasami osiąga to ekstremalne poziomy, w których Bieżące zatwierdzanie to więcej niż dwukrotne użycie pamięci fizycznej!
- 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.
Dotyczy to systemu Windows 10, jak zgłosił Process Explorer.
Ostateczne pytanie, na które chciałbym odpowiedzieć, brzmi: czy mogę zrezygnować z sztucznego pompowania pliku strony do poziomów, w których mój głodny SSD jest źle wyposażony do obsługi, aby właściwie 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”.)
windows-10
memory
memory-management
martixy
źródło
źródło
Odpowiedzi:
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):
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ć:
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”.
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.
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.
Przykro mi, ale jeśli napotykasz limit zatwierdzeń, możesz zrobić tylko trzy rzeczy:
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.
źródło