2011-01-16 5 views
5

Mój mały test warunków skrajnych, który przydziela losowe tablice długości (100..200 MB każdy) w pętli, pokazuje inne zachowanie na 64-bitowej maszynie Win7 i 32-bitowym XP (w VM). Oba systemy najpierw zwykle przydzielają tyle tablic, ile zmieści się w LOH. Następnie LOH staje się coraz większy, dopóki wirtualna przestrzeń adresowa nie zostanie wypełniona. Oczekiwane zachowanie do tej pory. Ale dalej - na dalsze prośby - oba zachowują się inaczej:Kiedy i jak jest przenoszona sterta .NET?

Podczas gdy na Win7 wyrzucany jest OutOfMemoryException (OOM), na XP wydaje się, że stertę zwiększa się, a nawet zamienia na dysk - przynajmniej OOM nie jest rzucany. (Nie wiem, czy to może mieć związek z XP działającym w wirtualnym pudełku).

Pytanie: Jak decyduje środowisko wykonawcze (lub system operacyjny?), Czy dla zarządzanych żądań przydzielania pamięci, czy jest zbyt duże aby uzyskać alokację, generowany jest OOM lub zwiększa się duża stertę obiektu - ewentualnie nawet zamieniona na dysk? Jeśli jest zamieniony, kiedy występuje OOM niż?

IMO to pytanie jest ważne dla wszystkich środowisk produkcyjnych, potencjalnie zajmujących się większymi zbiorami danych. Jakoś czuć się "bezpieczniej", aby wiedzieć, system raczej spowolniłby dramatycznie w takich sytuacjach (poprzez zamianę) niż po prostu wyrzucenie OOM. Przynajmniej powinno to być w jakiś sposób deterministyczne, prawda?

@Edit: aplikacja jest aplikacją 32-bitową, dlatego działa w trybie 32-bitowym na Win 7.

+0

"aż do fizycznej przestrzeni adresowej" nie masz na myśli wirtualnej przestrzeni adresowej tego procesu? – CodesInChaos

+0

Czy Twój program jest ustawiony na AnyCPU lub na 32BitOnly? Z pamięci w 64-bitowym programie nie powinno się łatwo. Spodziewałbym się, że komputer przestanie działać z powodu nadmiernej wymiany na długo przed tym. – CodesInChaos

+0

Masz rację: chodziło o "wirtualną przestrzeń adresową". I tak, prog kompiluje się do aplikacji 32-bitowej, uruchamiając WOW na Win7. – user492238

Odpowiedz

8

Obowiązują normalne zasady, zarządzany proces nie jest traktowane inaczej przez menedżera pamięci systemu Windows. Ostatecznym źródłem porcji pamięci jest menedżer pamięci Windows. Jeśli nie może znaleźć dziury w przestrzeni adresowej pamięci wirtualnej, aby dopasować żądaną alokację pamięci, to nie powiedzie się wywołanie VirtualAlloc(), a CLR wygeneruje OOM.

To samo dotyczy zamiany, jeśli strony w pamięci RAM są potrzebne do odwzorowania stron innych procesów, a nawet stron tego samego procesu, wtedy zostaną zamienione. Z OOM nie wiąże się to inaczej.

Nie można założyć, że będzie działał dokładnie tak samo na XP jak na Win7 x64. Uzyskanie OOM na platformie x64 podczas budowania celu programowego AnyCPU jest dość nietypowe, 64-bitowy system operacyjny ma bardzo dużą przestrzeń adresową pamięci wirtualnej. Górny limit jest ustalany na podstawie maksymalnego rozmiaru pliku stronicowania. 32-bitowy program będzie działał w warstwie emulacji WOW, może mieć przestrzeń adresową o wielkości 4 GB, jeśli ustawisz bit opcji LARGEADDRESSAWARE za pomocą Editbin.exe.

Możesz użyć narzędzia VMMap SysInteral, aby zobaczyć, w jaki sposób przestrzeń adresowa twojego procesu jest wyryta.

+1

"Jeśli nie może znaleźć dziury w przestrzeni adresowej pamięci wirtualnej, aby dopasować żądaną alokację pamięci, to nie powiedzie się wywołanie HeapAlloc(), a CLR generuje OOM." - ale dlaczego hack to nie stronicowanie niż? Przynajmniej powinno, jeśli wirtualna przestrzeń nie jest jeszcze w pełni wykorzystana, ale nie można znaleźć innej pamięci RAM? – user492238

+1

Dwa * bardzo * różne rzeczy. Stronicowanie następuje, gdy trzeba znaleźć * fizyczną * pamięć. BARAN. Przydziały pamięci występują w * wirtualnej * pamięci. Proces 32-bitowy ma 2 gigabajty, niezależnie od ilości zainstalowanej pamięci RAM. Suma wszystkich pamięci wirtualnych przydzielonych przez wszystkie procesy jest ograniczona tylko przez plik stronicowania, a nie przez RAM. –

+1

Więc 2 GB (trochę TB na 64bit) to tylko teoretyczne ograniczenia?Menedżer pamięci zamienia się, dopóki nie zostanie wypełniony rozmiar pliku stronicowania * część *, który jest zarezerwowany dla procesu? A jeśli ta część pasuje nawet do pamięci RAM, to nawet się nie wymienia? To mogłoby odpowiedzieć na pytanie – user492238

Powiązane problemy