Dlaczego nie uzywasz odsmiecacza (ang. garbage collector)?

0

W poprzedniej mojej ankiecie wyszlo, ze odsmiecacze sa niepopularne i wiekszosc woli bawic sie recznym new/delete i ryzykowac wiole... Ciekaw jestem dlaczego.

0

Np. jesli chodzi o Delphi 8 to odsmieczacz zwalnia dany obiekt gdy nie jest juz wykorzystywany. Jest to bardzo wygodna funkcja gdyz zapobiega wyciekom pamieci i zwalnia od uzywania destruktorow. Nieraz jednak uzycie destruktora staje sie konieczne - np. gdy w konstruktorze otwieramy jakis plik z prawami do zapisu zaden inny program nie moze wtedy zapisac czegos do pliku co wiaze sie z blokada owego pliku. W takich sytuacjach nie mozemy sobie pozwolic na oczekiwanie na akcje odsmieczacza - sami musimy zadbac o zwolnienie klasy, a tym samym zasobow w momencie gdy przestajemy korzystac z danego pliku.

0

Nieraz jednak uzycie destruktora staje sie konieczne - np. gdy w konstruktorze otwieramy jakis plik z prawami do zapisu zaden inny program nie moze wtedy zapisac czegos do pliku co wiaze sie z blokada owego pliku. W takich sytuacjach nie mozemy sobie pozwolic na oczekiwanie na akcje odsmieczacza - sami musimy zadbac o zwolnienie klasy, a tym samym zasobow w momencie gdy przestajemy korzystac z danego pliku.

W C++ mozna napisac odsmiecacz, ktory wywoluje destruktory. W Delphi tak sie nie dzieje? A nie ma finalizacji?

0

W C++ mozna napisac odsmiecacz, ktory wywoluje destruktory. W Delphi tak sie nie dzieje? A nie ma finalizacji?

Chodzi o to, ze chcemy miec natychmiast usuniety obiekt i zamkniety plik.
Uzywajac odsmiecacza, musimy go recznie wywolac.

Ja uzywam odsmiecacza tylko w Javie :)
Dobry programista, powinien poznac co to jest alokowanie i zwalnianie pamieci i nauczyc sie je dobrze obslugiwac, aby pozniej nie miec klopotow. Dobrze jest, jak przejedzie sie na wlasnych (najlepiej prostych) programach. Jak spedzi pol dnia szukajac bledu, to nauczy sie zwalniac pamiec :)
Oczywiscie, przy duzych projektach, nie mozna sobie juz poeksperymentowac. Wowczas odsmiecacz okazuje sie niesamowicie przydatny. Ale trzeba tez rozwazyc priorytety. Czy mozemy poswiecic troche wiecej czasu i uwagi, aby zaprogramowac porzadnie program wykorzystujac do tego standardowe mechanizmy alokowania pamieci czy moze niesamowicie nam sie spieszy i jestesmy sklonni poswiecic troche wiecej pamieci i czasu, aby uzyc odsmiecacza.
Niestety w tym drugim przypadku, gdy nam sie mocno spieszy, odsmiecacz i tak niewiele pomoze, bo usunie tylko czesc bledow, ktore zrobimy pedzac, by zdarzyc z terminami.
Jest jeszcze jeden argument przeciwko odsmiecaczom (oprocz wiekszego zuzycia pamieci i czasu). Otoz sa systuacje, w ktorych latwiej wykorzystac istniejacy destruktor niz pisac dodatkowa metode "deinit" :)

0

Czy mozemy poswiecic troche wiecej czasu i uwagi, aby zaprogramowac porzadnie program wykorzystujac do tego standardowe mechanizmy alokowania pamieci czy moze niesamowicie nam sie spieszy i jestesmy sklonni poswiecic troche wiecej pamieci i czasu, aby uzyc odsmiecacza.

Problem w tym, ze bardzo czesto w duzych projektach tak sie nie da - to "troche wiecej czasu i uwagi" sprowadza sie do nieustannego szukania wyciekow, walki z segfaultami i analizowania cudzego kodu. Pomysl co sie dzieje, jesli program pisze wiecej osob. Musieliby miec bardzo dobre linie komunikacji i bardzo dobre standardy kodowania, zeby uniknac bledow.

Jest jeszcze jeden argument przeciwko odsmiecaczom (oprocz wiekszego zuzycia pamieci i czasu). Otoz sa systuacje, w ktorych latwiej wykorzystac istniejacy destruktor niz pisac dodatkowa metode "deinit"

Sa odsmiecacze wywolujacye destruktory (te z ~) - wtedy nie jest to konieczne. Ale z tym plikiem to masz racje, wtedy trzeba przejsc na reczne zarzadzanie pamiecia, albo zrobic osobna metode.

Co do wiekszego zuzycia czasu/pamieci w odsmiecaczach, to jeszcze troche o tym powiem, ale na razie nic nie bede sugerowal, zeby nie zaklocac wynikow ankiety...

0

Problem w tym, ze bardzo czesto w duzych projektach tak sie nie da - to "troche wiecej czasu i uwagi" sprowadza sie do nieustannego szukania wyciekow, walki z segfaultami i analizowania cudzego kodu. Pomysl co sie dzieje, jesli program pisze wiecej osob. Musieliby miec bardzo dobre linie komunikacji i bardzo dobre standardy kodowania, zeby uniknac bledow.

Dlatego tez napisalem, ze nalezy rozwazyc, co jest lepsze dla projektu.

Co do wiekszego zuzycia czasu/pamieci w odsmiecaczach, to jeszcze troche o tym powiem, ale na razie nic nie bede sugerowal, zeby nie zaklocac wynikow ankiety...

Tak, pamietam posty dot. odsmiecaczy o narzucie mniejszym niz 150% ;)

0

Tak, pamietam posty dot. odsmiecaczy o narzucie mniejszym niz 150% ;)

???? 150%??? To chyba jakies "Home Made GC" albo "Reference Counting*"!!!

Na ogol odsmiecacze daja narzuty < 5-25% (jesli pracuja na systemowym alokatorze), ale mozliwe jest do uzyskania nawet znaczne przyspieszenie pracy aplikacji wzgledem odsmiecania recznego w przypadkach:

  • Odsuniecie zwalniania pamieci na czas, kiedy aplikacja czeka na reakcje uzytkownika / urzadzenia - wtedy oszczedza sie na wywolywaniu "free", ktore jest b. wolne.
  • Przesuniecie zwalniania pamieci na drugi procesor.
  • Uzycie odsmiecacza z dedykowanym alokatorem - zwiekszenie lokalnosci odwolan i zwiekszenie celnosci "cache'owania" oraz uproszczenie alokatora / dealokatora - porownaj szybkosc malloc w C i new w Javie (jesli Ci sie nie chce: Java dziala tu ponad 3 razy szybciej niz C).

J.Boehm testowal ten drugi przypadek i w niektorych programach uzyskal przyspieszenie ponad 1.5-krotne wzgledem recznego malloc/free (gdzies wygooglalem jakas jego prace naukowa, ale nie pamietam juz gdzie).

0

Tak, pamietam posty dot. odsmiecaczy o narzucie mniejszym niz 150% ;)

???? 150%??? To chyba jakies "Home Made GC" albo "Reference Counting*"!!!

To nie ja napisalem :P
http://4programmers.net/Forum/viewtopic.php?id=54031&post=138080

0

Szczerze powiedziawszy, to myślalem, że takie ustrojstwo jest tylko i wyłącznie w Javie. Nie słyszałem o tym w C/C++.

A co do samego C++, to nigdy nie użyłem malloc/free - nawet nie wiem dokładnie jak to działa [green]. A w swoich programach bardzo często zarządzam pamięcią dynamicznie. Przez new/delete.

0

Szczerze powiedziawszy, to myślalem, że takie ustrojstwo jest tylko i wyłącznie w Javie. Nie słyszałem o tym w C/C++.

W Javie jest standardowo, a do innych mozna sobie doinstalowac, o ile ktos napisal.

A co do samego C++, to nigdy nie użyłem malloc/free - nawet nie wiem dokładnie jak to działa [green]. A w swoich programach bardzo często zarządzam pamięcią dynamicznie. Przez new/delete.

W C++ nie musiales, ale w czystym C nie mialbys wyjscia :)

0

W C++ nie ma w standardzie odsmiecacza, ale mozesz sobie dociagnac roznego rodzaju biblioteki,
np. RTGC, BDW GC (ktory nie wiedziec czemu ma aspiracje do stania sie standardem), Smieciuch i jeszcze
pare innych. Odsmiecacze sa rozne i kazdy ma nieco inny zakres zastosowan,
w ktorym dziala najlepiej, dlatego tworcy C++ nie dolaczyli do biblioteki standardowej
zadnych takich rozwiazan w przeciwienstwie do Suna, ktory zrobil tak w Javie (eee..
kopiujacy GC typu stop-the-world - min. 100% narzutu pamieciowego i przemiatanie
wszystkich stron z kazda kolekcja, mimo to chodzi nawet w miare dobrze).

A operatory new/delete wywoluja systemowe malloc/free. Poza tym, ze sa wygodniejsze w uzyciu,
bo wywoluja konstruktory/destruktory i troche inaczej sie je "pisze", to
w zasadzie robia to samo.

0

Właściwe po co taki odśmiecacz?? jak się komuś niechce pisać delete to zawsze pozostaje klasa auto_ptr :P

0

Właściwe po co taki odśmiecacz?? jak się komuś niechce pisać delete to zawsze pozostaje klasa auto_ptr :P

Eh. Bo wlasnie na ogol nie wiadomo w ktorym momencie napisac to delete. auto_ptr jest tylko glupim wskaznikiem, ktory wprawdzie uniemozliwia popelnienie pewnych bledow, ale jest w wiekszosci sytuacji bezuzyteczny. Np. bez sensu jest robienie kolekcji w ktorej trzymasz obiekty typu auto_ptr.

A odsmiecacze sa potrzebne przy duzych projektach. Gdzie wstawisz delete, jesli masz 2 moduly pisane przez roznych ludzi, ktore wspoldziela te same obiekty? Czy jak niszczysz kolekcje, to czy niszczy wszystkie obiekty przy jej zwalnianiu, czy musi to zrobic programista przed zniszczeniem kolekcji? A co jesli jakis wskaznik na obiekt w tej zwalnianej wlasnie kolekcji zawieruszyl sie gdzies w jakiejs innej strukturze? (bo jakis programista sobie cache'owanie zrobil, zeby przyspieszyc dostep?). Problemow sa setki. GC je pomaga rozwiazac.

0

A skąd taki Garbage Collector wie że przydzielona pamięć nie będzie już wykorzystywana?? Sprawdza wszystkie wskaźniki czy jak ?? To muszi być strasznie wolne!!

0

A skąd taki Garbage Collector wie że przydzielona pamięć nie będzie już wykorzystywana?? Sprawdza wszystkie wskaźniki czy jak ?? To muszi być strasznie wolne!!

Owszem, sprawdza wskazniki, ale niekoniecznie wszystkie (generacyjne gc) i wcale nie jest to wolne. Heca polega na tym, ze sprawdzanie odbywa sie jedynie raz na jakis czas. Na sprawdzanie oczywiscie jest potrzebna jakas niewielka moc obliczeniowa, ale bardzo czesto jest ona rownowazona przez to, ze przy obecnosci odsmiecacza mozna napisac prostszy alokator/dealokator, co z kolei przyspiesza wykonywanie aplikacji. Wskaznikow zreszta jest relatywnie malo w porownaniu z reszta danych. A nawet jesli uzywa sie alokatora systemowego, to taka seria wywolan:

new, delete, new, delete, new, delete itd....

bedzie sie wykonywala wolniej niz taka:

new, new, new, new..... , delete, delete, delete

Jesli nadal myslisz, ze GC jest wolne, to napisz sobie programik tworzacy 1000000 obiektow w Javie i dla porownania taki sam C. Zobaczysz, ze ten w Javie wykona sie 3 razy szybciej - wlasnie dzieki temu, ze w Javie jest GC+dedykowany alokator, a nie malloc(). Poza tym sprawe badalo juz wielu naukowcow i w zaleznosci od jezyka, algorytmow GC i programu, uzyskuje sie od trzykrotnego przyspieszenia programu do spowolnienia o jakies 30%.

1 użytkowników online, w tym zalogowanych: 0, gości: 1