Zamknięte . To pytanie musi być bardziej
skoncentrowane . Obecnie nie przyjmuje odpowiedzi.
Komentarze
Odpowiedź
Odśmiecanie pamięci wymaga struktur danych dla śledzenie przydziałów i / lub liczenie referencji. To powoduje obciążenie pamięci, wydajności i złożoności języka. C ++ został zaprojektowany tak, aby być „blisko metalu”, innymi słowy, ma wyższą wydajność w porównaniu z wygodnymi funkcjami. W innych językach ten kompromis wygląda inaczej. Jest to jeden z czynników branych pod uwagę przy wyborze języka, na który preferujesz nacisk.
To powiedziawszy, istnieje wiele schematów liczenia referencji w C ++, które są dość lekkie i wydajne, ale znajdują się one w bibliotekach, zarówno komercyjnych, jak i open source, a nie jako część samego języka. Zliczanie odwołań do zarządzania okresem istnienia obiektu nie jest tym samym, co wyrzucanie elementów bezużytecznych, ale rozwiązuje wiele podobnych problemów i lepiej pasuje do podstawowego podejścia w C ++.
Komentarze
Odpowiedź
Ściśle mówiąc, w języku C nie ma zarządzania pamięcią. malloc () i free () nie są słowami kluczowymi w języku, a jedynie funkcjami wywoływanymi z biblioteki.To rozróżnienie może być teraz pedantyczne, ponieważ malloc () i free () są częścią standardowej biblioteki C i będą dostarczane przez każdą zgodną ze standardami implementację C, ale w przeszłości nie zawsze tak było.
Dlaczego miałbyś chcieć języka bez standardu zarządzania pamięcią? To sięga do początków C jako „przenośnego zestawu”. Istnieje wiele przypadków sprzętu i algorytmów, które mogą skorzystać ze specjalistycznych technik zarządzania pamięcią lub nawet ich wymagać. O ile wiem, nie ma sposobu na całkowite wyłączenie natywnego zarządzania pamięcią Javy i zastąpienie go własnym. Jest to po prostu niedopuszczalne w niektórych sytuacjach wymagających dużej wydajności / minimalnych zasobów. C zapewnia prawie całkowitą elastyczność wyboru konkretnej infrastruktury Twój program będzie używany. Zapłacona cena jest taka, że język C zapewnia bardzo niewielką pomoc w pisaniu poprawnego, wolnego od błędów kodu.
Komentarze
Odpowiedź
Prawdziwą odpowiedzią jest to, że jedynym sposobem bezpiecznym i wydajnym mechanizmem usuwania elementów bezużytecznych jest obsługę na poziomie języka dla niejasnych odniesień. (Lub odwrotnie, brak obsługi na poziomie języka dla bezpośredniej manipulacji pamięcią.)
Java i C # mogą to zrobić, ponieważ mają specjalne typy odwołań, którymi nie można manipulować. Daje to środowisku wykonawczemu swobodę wykonywania takich czynności, jak przenoszenie przydzielonych obiektów w pamięci , co jest kluczowe dla wydajnej implementacji GC .
Dla przypomnienia, żadna nowoczesna implementacja GC nie korzysta z liczenia odwołań , więc jest to całkowicie czerwona śledź. Nowoczesne GC używają kolekcji pokoleniowej, w której nowe alokacje są traktowane zasadniczo w taki sam sposób, jak alokacje stosu w języku takim jak C ++, a następnie okresowo wszystkie nowo przydzielone obiekty, które wciąż istnieją, są przenoszone do oddzielnej przestrzeni „ocalałej” i przez całe pokolenie obiektów jest natychmiast zwalnianych.
To podejście ma zalety i wady: zaletą jest to, że alokacje sterty w języku obsługującym GC są tak szybkie, jak alokacje stosu w języku, który nie” nie obsługuje GC, a wadą jest to, że obiekty, które wymagają czyszczenia przed zniszczeniem, wymagają oddzielnego mechanizmu (np. C # „s using
słowo kluczowe) albo ich kod czyszczący działa niedeterministycznie.
Zauważ, że jednym z kluczy do wysokowydajnego GC jest to, że musi istnieć obsługa języka dla specjalnej klasy odniesień. C nie ma obsługi tego języka i nigdy nie będzie; ponieważ C ++ ma przeciążenie operatorów, może emulować typ wskaźnika GC, chociaż musiałby być wykonany ostrożnie. W rzeczywistości, kiedy Microsoft wynalazł swój dialekt języka C ++, który działałby w środowisku CLR (środowisko wykonawcze .NET), musiał wymyślić nową składnię dla „odwołań w stylu C #” (np. Foo^
), aby odróżnić je od „odniesień w stylu C ++” (np. Foo&
).
To, co ma C ++ i co jest regularnie używane przez programistów C ++, to inteligentne wskaźniki , które są tak naprawdę tylko mechanizmem zliczania odniesień. Nie uważałbym zliczania referencji za „prawdziwą” GC, ale zapewnia wiele takich samych korzyści, kosztem wolniejszej wydajności niż ręczne zarządzanie pamięcią lub prawdziwy GC, ale z zaletą deterministycznego niszczenia.
Ostatecznie odpowiedź naprawdę sprowadza się do funkcji projektowania języka. C dokonał jednego wyboru, C ++ dokonał wyboru, który umożliwił mu kompatybilność wsteczną z C, jednocześnie zapewniając alternatywy, które są wystarczająco dobre dla większości celów, a Java i C # dokonały innego wyboru, który jest niezgodny z C, ale jest również wystarczająco dobry do większości zastosowań. Niestety, nie ma srebrnej kuli, ale znajomość różnych dostępnych opcji pomoże ci wybrać właściwy dla programu, który aktualnie próbujesz zbudować.
Komentarze
Odpowiedź
Odpowiedź
„Wszystkie” garbage collector to proces, który uruchamia się okresowo sprawdzając, czy w pamięci znajdują się obiekty, do których nie ma odwołań, i czy są, usuwa je. (Tak, wiem, że to rażące uproszczenie). To nie jest własność języka, ale framework.
Na przykład istnieją zbieracze śmieci napisane dla C i C ++ – ten .
Jednym z powodów, dla których nie „dodano” języka do języka, może być ogromna ilość istniejącego kodu, który nigdy nie użyłby go, ponieważ używają własnego kodu do zarządzania pamięcią. Innym powodem może być być tak, że typy aplikacji napisanych w C i C ++ nie wymagają narzutu związanego z procesem czyszczenia pamięci.
Komentarze
Odpowiedź
C zostało zaprojektowane w czasach, gdy czyszczenie pamięci było ledwo opcja. Był również przeznaczony do zastosowań, w których zbieranie elementów bezużytecznych generalnie nie działałoby – bez oprogramowania, środowiska czasu rzeczywistego z minimalną ilością pamięci i minimalną obsługą środowiska wykonawczego. Pamiętaj, że C był językiem implementacji dla pierwszego uniksa, który działał na pdp-11 z 64 * K * bajtami pamięci. C ++ był pierwotnie rozszerzeniem C – wybór został już dokonany i bardzo trudno jest przeszczepić system czyszczenia pamięci do istniejącego języka. Jest to rodzaj rzeczy, która musi być wbudowana z parteru.
Odpowiedź
Nie mam dokładnych cytatów, ale zarówno Bjarne, jak i Herb Sutter mówią coś podobnego:
C ++ nie potrzebuje garbage collectora, ponieważ nie zawiera śmieci.
We współczesnym C ++ używasz inteligentnych wskaźników i dlatego nie masz żadnych śmieci.
Komentarze
Odpowiedź
Ty zapytaj, dlaczego te języki nie zostały zaktualizowane i zawierają opcjonalny moduł odśmiecania pamięci.
Problem z opcjonalnym czyszczeniem pamięci polega na tym, że nie można mieszać kodu, który używa różnych modeli. To znaczy, jeśli napiszę kod, który zakłada, że używasz garbage collectora, nie możesz go użyć w swoim programie, który ma wyłączoną funkcję czyszczenia pamięci. Jeśli to zrobisz, wycieknie wszędzie.
Odpowiedź
Jest wiele problemów, w tym …
- Chociaż GC został wynaleziony przed C ++ i prawdopodobnie przed C, zarówno C, jak i C ++ zostały zaimplementowane zanim GC zostały powszechnie zaakceptowane jako praktyczne.
- Nie można łatwo zaimplementować Język i platforma GC bez bazowego języka innego niż GC.
- Chociaż GC jest ewidentnie bardziej wydajne niż nie-GC dla kodu typowych aplikacji opracowanych w typowych skalach czasowych itp., Istnieją problemy, w których większy wysiłek programistyczny jest dobrą transakcją -off i wyspecjalizowane zarządzanie pamięcią przewyższy ogólne GC. Poza tym C ++ jest zazwyczaj bardziej efektywny niż większość języków GC, nawet bez dodatkowego wysiłku programistycznego.
- GC nie jest uniwersalnie bezpieczniejsze niż RAII w stylu C ++ . RAII umożliwia automatyczne czyszczenie zasobów innych niż pamięć, głównie dlatego, że obsługuje niezawodne i działające w czasie destruktory. Nie można ich łączyć z konwencjonalnymi metodami GC z powodu problemów z cyklami odniesienia.
- Języki GC mają swoją własną charakterystykę rodzaje pamięci przecieki, szczególnie dotyczące pamięci, która nigdy nie zostanie ponownie użyta, ale tam, gdzie istniały istniejące odniesienia, które nigdy nie zostały anulowane lub nadpisane. Konieczność zrobienia tego jawnie nie różni się w zasadzie od konieczności wyraźnego
delete
lub free
. Podejście GC nadal ma tę zaletę – nie ma żadnych wiszących odniesień – a analiza statyczna może wychwycić niektóre przypadki, ale znowu nie ma jednego idealnego rozwiązania dla wszystkich przypadków.
Zasadniczo, częściowo to. mniej więcej w wieku języków, ale i tak zawsze znajdzie się miejsce dla języków spoza GC – nawet jeśli jest to trochę niszowe miejsce. A poważnie, w C ++, brak GC nie jest wielkim problemem – twoja pamięć jest zarządzana inaczej, ale nie jest zarządzana.
C ++ zarządzany przez Microsofty ma przynajmniej pewną możliwość mieszania GC i nie GC w tej samej aplikacji, umożliwiając mieszanie i dopasowywanie zalet każdego z nich, ale nie mam doświadczenia, aby powiedzieć, jak dobrze to działa w praktyce.
Linki do powiązanych odpowiedzi z moich …
Odpowiedź
Czy możesz sobie wyobrazić pisanie programu obsługi urządzenia w języku z funkcją czyszczenia pamięci? Ile bitów może zejść linia podczas działania GC?
A może system operacyjny? Jak możesz rozpocząć czyszczenie pamięci zanim uruchomisz jądro?
C jest przeznaczony do niskiego poziomu zbliżonego do zadań sprzętowych. Problem? czy to taki fajny język, że jest dobrym wyborem również do wielu zadań na wyższym poziomie. Czesi językowi są świadomi tych zastosowań, ale muszą priorytetowo wspierać wymagania sterowników urządzeń, wbudowanego kodu i systemów operacyjnych.
Komentarze
Odpowiedź
Krótka i nudna odpowiedź na to pytanie jest taka, że dla ludzi, którzy piszą garbage collectorów, musi istnieć język niepotrzebny. Koncepcyjnie nie jest łatwo mieć język, który jednocześnie pozwala na bardzo precyzyjną kontrolę nad układem pamięci, i ma na wierzchu działający GC.
Drugie pytanie brzmi: dlaczego C i C ++ nie mają odśmiecaczy.Cóż, wiem, że C ++ ma kilka z nich, ale nie są one zbyt popularne, ponieważ są zmuszeni radzić sobie z językiem, który nie został zaprojektowany do GC w pierwszej kolejności, a ludzie, którzy nadal używają C ++ w ten wiek naprawdę nie jest typem, który pomija GC.
Ponadto zamiast dodawać GC do starego języka bez GC, w rzeczywistości łatwiej jest stworzyć nowy język, który ma większość taką samą składnię, ale obsługując GC. Java i C # są tego dobrymi przykładami.
Komentarze
Odpowiedź
Czyszczenie pamięci jest zasadniczo niezgodne z język systemowy używany do tworzenia sterowników dla sprzętu obsługującego DMA.
Jest całkowicie możliwe, że jedyny wskaźnik do obiektu byłby przechowywany w rejestrze sprzętowym jakiegoś urządzenia peryferyjnego. Ponieważ moduł odśmiecania pamięci nie wiedziałby w związku z tym pomyślałby, że obiekt jest nieosiągalny i zebrałby go.
Ten argument ma podwójne znaczenie dla kompaktowania GC. Nawet gdybyś uważał, aby zachować w pamięci odniesienia do obiektów używanych przez sprzętowe urządzenia peryferyjne, kiedy GC przenosi obiekt, nie wiedziałby, jak zaktualizować wskaźnik zawarty w rejestrze konfiguracji urządzeń peryferyjnych.
Więc teraz potrzebujesz mieszanki nieruchomych buforów DMA i obiektów zarządzanych przez GC, co oznacza, że masz wszystkie wady obu.
Komentarze
Odpowiedź
Ponieważ C & C ++ to języki stosunkowo niskiego poziomu przeznaczone do celów ogólnych, nawet np. do uruchomienia na 16-bitowym procesorze z 1 MB pamięci w systemie wbudowanym, który nie może pozwolić sobie na marnowanie pamięci przy użyciu gc.
Komentarze
Odpowiedź
W C ++ i C są odśmiecacze pamięci. Nie wiem, jak to działa w C, ale w C ++ możesz wykorzystać RTTI , aby dynamicznie wykryć swój graf obiektu i użyć go do czyszczenia pamięci.
O ile wiem, nie możesz pisać w Javie bez śmieciarki. Pojawiło się małe wyszukiwanie to .
Kluczowa różnica między Javą a C / C ++ polega na tym, że w C / C ++ wybór zawsze należy do Ciebie , podczas gdy w Javie często pozostajesz bez opcji z założenia.
Komentarze
t nakładają się.