2015-05-29 39 views
9

Jest to dobrze znany fakt, że odśmiecacz .NET nie tylko "usuwa" obiekty na stercie, ale także walczy z fragmentacją pamięci za pomocą kompresji pamięci. Z tego co rozumiem, w zasadzie pamięć jest kopiowana do nowego miejsca, a stare miejsce jest w pewnym momencie usunięte.W jaki sposób środowisko wykonawcze .NET przenosi pamięć?

Moje pytanie brzmi: jak to działa?

Najbardziej interesuje mnie fakt, że GC przebiega w osobnym wątku, co oznacza, że ​​obiekt, nad którym pracujemy, może zostać przeniesiony przez GC podczas wykonywania naszego kodu.

szczegóły techniczne pytanie

Aby zilustrować, pozwól mi wyjaśnić moje pytanie bardziej szczegółowo:

class Program 
{ 
    private int foo; 
    public static void Main(string[] args) 
    { 
     var tmp = new Program(); // make an object 
     if (args.Length == 2) // depend the outcome on a runtime check 
     { 
      tmp.foo = 12;  // set value *** 
     } 
     Console.WriteLine(tmp.foo); 
    } 
} 

W tej niewielkiej przykład możemy stworzyć obiekt i ustawić prostą zmienną na zasadzie obiekt. Punkt "***" to wszystko, co ma znaczenie dla pytania: jeśli adres "tmp" się rusza, "foo" odwoła się do czegoś niepoprawnego i wszystko się zepsuje.

Śmieciarka działa w oddzielnym wątku. Tak więc, o ile wiem, "tmp" może zostać przeniesiony podczas tej instrukcji, a "foo" może zakończyć się nieprawidłową wartością. Ale w jakiś sposób magia się dzieje i tak nie jest.

chodzi o disassembler, zauważyłem, że skompilowany program naprawdę ma adres „foo” i porusza się w wartości '12:

000000ae 48 8B 85 10 01 00 00 mov   rax,qword ptr [rbp+00000110h] 
000000b5 C7 40 08 0C 00 00 00 mov   dword ptr [rax+8],0Ch 

I mniej lub bardziej oczekiwany, aby zobaczyć wskaźnik pośredni tutaj który można aktualizować - ale najwyraźniej GC działa mądrzej niż to.

Ponadto nie widzę żadnej synchronizacji wątku, która sprawdza, czy obiekt został przeniesiony. W jaki sposób GC aktualizuje stan w wykonywanym wątku?

Jak to działa? A jeśli GC nie przenosi tych obiektów, jaka jest "reguła", która definiuje czy obiekty lub obiekty nie są ruchome?

+0

Należy pamiętać, że stare wersje .NET używały GC "stop-the-world", więc zarządzane wątki zostały zatrzymane, GC zostało wykonane, a wątki zarządzane zostały przywrócone. – xanatos

+0

Czy zdajesz sobie sprawę, że GC wznawia dane tylko wtedy, gdy twoja instancja 'Programu' jest poza zakresem? Tak długo, jak Twoja aplikacja jest uruchomiona, zawsze będziesz miał poprawną wartość dla 'foo'. – HimBromBeere

Odpowiedz

5

.NET GC jest (przynajmniej częściowo) GC "stop-the-world": zatrzymuje zarządzane wątki przed wykonaniem swojej pracy, wykonuje swoją pracę, a następnie uruchamia ponownie zarządzane wątki.

"Stacja robocza" GC może być współbieżna (więc częściowo nie zatrzymać się na świecie), ale należy zwrócić uwagę na https://msdn.microsoft.com/library/ee851764.aspx.

Podczas korzystania ze zbierania śmieci ze stacji roboczej przy jednoczesnym zbieraniu śmieci, odzyskane obiekty nie są kompaktowane, więc rozmiar sterty może być taki sam lub większy (fragmentacja może sprawić, że będzie wyglądała na większą).

Należy pamiętać, że przy całym GC, gen0 i gen1 są zawsze stop-the-world. Dzięki temu mogą bezproblemowo przenosić bloki pamięci. Tylko gen2 może być wykonany w tle przez niektóre GC w niektórych konfiguracjach (to link, informacje są trochę podzielone na całej stronie), więc zawsze jest moment "the-world-is-stop", gdzie pamięć, która została uwolniony może być zagęszczony.

+0

Należy zauważyć, że współbieżny GC został skutecznie zastąpiony "tłem" GC zaczynającym się od .Net 4. [Niektóre szczegóły tutaj] (https://msdn.microsoft.com/en-us/library/ee787088%28v=vs.110%29 .aspx) –

+0

@MatthewWatson A od wersji 4.5 nawet serwer ma "tła" GC. Nadal gen0 i gen1 są zawsze "stop-the-world". Tylko gen2 działa z innego wątku – xanatos

+0

@xanatos Oznaczałoby to, że kiedy "zatrzymujesz świat", wiesz dokładnie, gdzie znajduje się licznik programu, jakie są jego nazwy w rejestrach, gdzie są miejscowi - itd. Po GC kontynuujesz przywracając wszystko to (itp.) - jeszcze gorzej: robisz to wszystko na innym procesorze niż tam, gdzie aktualnie pracujesz? Nie wiedziałbym nawet, jak zacząć, gdybym chciał wprowadzić to w życie ... Jak, na Boga, robisz coś takiego? – atlaste

Powiązane problemy