Jak działa nowy automatyczny mechanizm zliczania referencji?

Czy ktoś może mi krótko wyjaśnić jak działa ARC? Wiem, że to różni się od zbierania śmieci, ale zastanawiałem się, jak to działa.

Ponadto, jeśli ARC robi to, co robi GC bez utrudniania wydajności, to dlaczego Java używa GC? Dlaczego nie używa również ARC?

Author: Brad Larson, 2011-06-17

5 answers

Każdy nowy programista, który przychodzi do Objective - C musi nauczyć się sztywnych zasad, kiedy zachować, zwolnić i autorelease obiektów. Reguły te określają nawet konwencje nazewnictwa, które implikują liczbę zatrzymanych obiektów zwracanych z metod. Zarządzanie pamięcią w Objective-C staje się drugą naturą, gdy weźmiesz sobie do serca te zasady i zastosujesz je konsekwentnie, ale nawet najbardziej doświadczeni programiści Cocoa od czasu do czasu wpadają w ucho.

Z analizatorem statycznym Clang, twórcy LLVM zdałem sobie sprawę, że reguły te są na tyle niezawodne, że mogą zbudować narzędzie do wskazywania wycieków pamięci i nadmiernych wycieków w ścieżkach, które przebiega twój kod.

Kolejnym logicznym krokiem jest automatyczne zliczanie referencji (ARC). Jeśli kompilator może rozpoznać, gdzie powinieneś zachować i zwolnić obiekty, dlaczego nie wstawić tego kodu za Ciebie? Sztywne, powtarzalne zadania są tym, w czym kompilatorzy i ich bracia są świetni. Ludzie zapominają o rzeczach i popełniają błędy, ale komputery są bardziej spójne.

Nie jest to jednak całkowicie wolne od martwienia się o zarządzanie pamięcią na tych platformach. Opisuję podstawową kwestię, na którą należy uważać (zachować cykle) w mojej odpowiedzi tutaj , która może wymagać trochę przemyślenia z twojej strony, aby zaznaczyć słabe wskaźniki. Jest to jednak niewielkie w porównaniu z tym, co zyskujesz w ARC.

W porównaniu do ręcznego zarządzania pamięcią i zbierania śmieci, ARC daje Ci to, co najlepsze z obu światów, wycinając konieczność napisania kodu zachowującego / uwalniającego, jednak nie mając profili pamięci zatrzymującej i sawtooth widzianych w środowisku śmieci. O jedyne zalety garbage collection nad tym są jego zdolność do radzenia sobie z cykli zatrzymywania i fakt, że atomowe przypisania własności są niedrogie (jak omówiono tutaj). Wiem, że zastępuję cały mój istniejący kod Mac GC implementacjami ARC.

Jeśli chodzi o to, czy można to rozszerzyć na inne języki, wydaje się, że wokół systemu zliczania referencji w Objective-C. Może być trudno zastosować to do Javy lub innych języków, ale nie wiem wystarczająco dużo o szczegółach kompilatora niskiego poziomu, aby sformułować tam ostateczne oświadczenie. Biorąc pod uwagę, że to Apple forsuje ten wysiłek w LLVM, Objective-C będzie pierwszym, chyba że inna strona przeznaczy na to znaczne środki.

Odsłona tego szokującego developera na WWDC, więc ludzie nie byli świadomi, że coś takiego może być załatwione. Z czasem może pojawić się na innych platformach, ale na razie jest dostępny wyłącznie dla LLVM i Objective-C.]}

 240
Author: Brad Larson,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2017-05-23 12:02:35

ARC jest po prostu odtwarzaniem starego retain/release (MRC) z kompilatorem zastanawiającym się, kiedy wywołać retain/release. Będzie miał większą wydajność, niższe zużycie pamięci szczytowej i bardziej przewidywalną wydajność niż system GC.

Z drugiej strony niektóre typy struktury danych nie są możliwe Z ARC (lub MRC), podczas gdy GC może sobie z nimi poradzić.

Jako przykład, jeśli masz klasę o nazwie node, a node ma NSArray dzieci i jedno odniesienie do jej rodzica, które " po prostu działa" z GC. Z ARC (i ręcznym zliczaniem referencji) masz problem. Każdy węzeł będzie odwoływany od jego dzieci, a także od jego rodzica.

Jak:

A -> [B1, B2, B3]
B1 -> A, B2 -> A, B3 -> A

Wszystko jest w porządku, gdy używasz (powiedzmy przez zmienną lokalną).

Kiedy skończysz z tym (i B1/B2/B3), system GC ostatecznie zdecyduje się spojrzeć na wszystko, co może znaleźć, zaczynając od rejestrów stosu i procesora. Nigdy nie znajdzie A, B1,B2, B3, więc sfinalizuje je i odzyska pamięć do innych obiektów.

Kiedy używasz ARC lub MRC i kończysz na A, to ma refcount 3 (B1, B2 i B3 wszystkie odwołują się do niego), A B1/B2 / B3 będą miały liczbę referencji równą 1 (NSArray A zawiera jedno odniesienie do każdego). Więc wszystkie te obiekty pozostają żywe, chociaż nic nie może ich użyć.

Powszechnym rozwiązaniem jest decyzja, że jedno z tych odniesień musi być słabe (nie przyczyniać się do liczby odniesień). To będzie działać dla niektórych wzorców użytkowania, na przykład jeśli odniesienie B1/B2 / B3 tylko przez A. Jednak w innych wzorach zawodzi. Na przykład, jeśli czasami będziesz trzymać się B1 i spodziewasz się wspiąć się z powrotem przez wskaźnik nadrzędny i znaleźć A. ze słabym odniesieniem, jeśli trzymasz tylko B1, A może (i normalnie będzie) wyparować i wziąć B2 i B3 z nim.

Czasami nie jest to problemem, ale niektóre bardzo przydatne i naturalne sposoby pracy ze złożonymi strukturami danych są bardzo trudne w użyciu Z ARC / MRC.

Więc Arc celuje w to samo problemy z celami GC. Jednak ARC działa na bardziej ograniczonym zestawie wzorców użycia niż Gc, więc jeśli weźmiesz język GC (jak Java) i zaszczepisz na nim coś takiego jak ARC, niektóre programy nie będą już działać (lub przynajmniej wygenerowałyby Tony porzuconej pamięci i mogą powodować poważne problemy z wymianą lub zabraknie pamięci lub przestrzeni wymiany).

Można również powiedzieć, że ARC stawia większy priorytet na wydajność (a może przewidywalność), podczas gdy GC stawia większy priorytet na bycie ogólnym rozwiązanie. W rezultacie GC ma mniej przewidywalne zapotrzebowanie na procesor / pamięć i niższą wydajność (Zwykle) niż ARC, ale może obsłużyć dowolny schemat użytkowania. ARC będzie działać znacznie lepiej dla wielu wielu popularnych wzorców użytkowania ,ale dla kilku (valid!) wzorce użytkowania spadnie i umrze.

 21
Author: Stripes,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2013-11-04 17:03:53

Magia

Ale bardziej konkretnie ARC działa robiąc dokładnie to, co byś zrobił ze swoim kodem (z pewnymi drobnymi różnicami). ARC jest technologią czasu kompilacji, w przeciwieństwie do GC, która jest runtime i wpłynie negatywnie na wydajność. ARC będzie śledzić odniesienia do obiektów za Ciebie i syntetyzować metody zachowaj/zwolnij/autorelease zgodnie z normalnymi regułami. Z tego powodu ARC może również zwolnić rzeczy, jak tylko nie są już potrzebne, zamiast rzucać je do puli autorelease wyłącznie ze względu na konwencję.

Niektóre inne ulepszenia obejmują zerowanie słabych odniesień, automatyczne kopiowanie bloków do sterty, przyspieszenie całej planszy (6x dla pul autorelease!).

Bardziej szczegółowe omówienie tego, jak to wszystko działa, znajduje się w Docs LLVM na ARC.

 4
Author: Joshua Weinberg,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2011-06-17 13:08:25

Różni się znacznie od zbierania śmieci. Czy widziałeś ostrzeżenia, które mówią ci, że możesz przeciekać obiekty na różnych liniach? Te stwierdzenia mówią nawet, w jakiej linii przydzieliłeś obiekt. To było o krok dalej i teraz Można wstawić retain/release wypowiedzi w odpowiednich miejscach, lepsze niż większość programistów, prawie 100% czasu. Czasami zdarzają się dziwne przypadki zachowanych obiektów, z którymi musisz mu pomóc.

 3
Author: FreeAsInBeer,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2011-06-17 12:49:52

Bardzo dobrze wyjaśnione przez dokumentację deweloperów Apple. Przeczytaj "Jak działa ARC"

Aby upewnić się, że instancje nie znikają, gdy są jeszcze potrzebne, ARC śledzi, ile właściwości, stałych i zmiennych odnosi się obecnie do każdej instancji klasy. ARC nie spowoduje dealokacji instancji, o ile nadal istnieje co najmniej jedno aktywne odniesienie do tej instancji.

Aby upewnić się, że instancje nie znikają, gdy są jeszcze potrzebne, Arc tracks ile właściwości, stałych i zmiennych odnosi się obecnie do każdej instancji klasy. ARC nie spowoduje dealokacji instancji, o ile nadal istnieje co najmniej jedno aktywne odniesienie do tej instancji.

Aby poznać Diff. między Garbage collection a ARC: Read this

 0
Author: Lalit Kumar,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2017-05-23 11:54:33