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?
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
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