Po udzieleniu odpowiedzi na pytanie, w jaki sposób wymusić zwolnienie obiektów w Javie (facet wyczyścił HashMap o pojemności 1,5 GB) System.gc()
, powiedziano mi, że wywoływanie System.gc()
ręczne jest złe , ale komentarze nie były całkowicie przekonujące. Ponadto nikt nie odważył się głosować za moją odpowiedzią ani głosować za nią.
Powiedziano mi tam, że to zła praktyka, ale potem powiedziano mi również, że uruchamianie śmieciarza nie zatrzymuje już systematycznie świata, i że JVM może go skutecznie wykorzystać tylko jako podpowiedź, więc jestem rodzajem ze stratą.
Rozumiem, że JVM zwykle wie lepiej niż Ty, kiedy potrzebuje odzyskać pamięć. Rozumiem również, że martwienie się o kilka kilobajtów danych jest głupie. Rozumiem również, że nawet megabajty danych nie są tym, co było kilka lat temu. Ale nadal 1,5 gigabajta? I wiesz, że w pamięci kręci się około 1,5 GB danych; to nie jest strzał w ciemność. Czy jest System.gc()
systematycznie zły, czy jest jakiś moment, w którym wszystko jest w porządku?
Pytanie jest więc podwójne:
- Dlaczego dzwonienie jest lub nie jest złą praktyką
System.gc()
? Czy w niektórych implementacjach jest to jedynie wskazówka dla JVM, czy zawsze jest to pełny cykl zbierania? Czy istnieją naprawdę implementacje śmieciarek, które mogą wykonywać swoją pracę bez zatrzymywania świata? Proszę rzucić nieco światła na różne twierdzenia, które ludzie poczynili w komentarzach do mojej odpowiedzi . - Gdzie jest próg? Czy dzwonienie nigdy nie jest dobrym pomysłem
System.gc()
, czy są chwile, kiedy jest to do przyjęcia? Jeśli tak, to jakie są teraz czasy?
źródło
Odpowiedzi:
Powodem, dla którego wszyscy zawsze mówią, aby unikać,
System.gc()
jest to, że jest to całkiem dobry wskaźnik fundamentalnie zepsutego kodu . Każdy kod, który zależy od poprawności, jest z pewnością uszkodzony; wszystkie, które polegają na wydajności, najprawdopodobniej są zepsute.Nie wiesz, pod jakim typem śmieciarza działasz. Z pewnością są takie, które nie „zatrzymują świata”, jak twierdzisz, ale niektóre maszyny JVM nie są tak inteligentne lub z różnych powodów (być może są na telefonie?) Tego nie robią. Nie wiesz co to zrobi.
Nie ma też gwarancji, że nic nie zrobisz. JVM może po prostu całkowicie zignorować twoją prośbę.
Kombinacja „nie wiesz, co to zrobi”, „nie wiesz, czy to w ogóle pomoże” i „nie powinieneś tego tak nazywać”, dlatego ludzie tak zdecydowanie mówią tak ogólnie nie powinieneś tego nazywać. Myślę, że jest to przypadek „jeśli musisz zapytać, czy powinieneś tego używać, nie powinieneś”
EDYCJA, aby rozwiązać kilka problemów z drugiego wątku:
Po przeczytaniu wątku, który połączyłeś, chciałbym zwrócić uwagę na jeszcze kilka rzeczy. Po pierwsze, ktoś zasugerował, że wywołanie
gc()
może zwrócić pamięć do systemu. To z pewnością niekoniecznie prawda - sama sterta Java rośnie niezależnie od przydziałów Java.W miarę upływu czasu JVM będzie przechowywać pamięć (wiele dziesiątek megabajtów) i w razie potrzeby powiększy stertę. Niekoniecznie zwraca tę pamięć do systemu, nawet gdy zwalniasz obiekty Java; całkowicie za darmo można trzymać przydzieloną pamięć do wykorzystania w przyszłych alokacjach Java.
Aby pokazać, że możliwe jest, że
System.gc()
nic nie robi, zobacz:http://bugs.sun.com/view_bug.do?bug_id=6668279
aw szczególności, że istnieje opcja -XX: DisableExplicitGC VM.
źródło
System.gc()
jest to przydatne, a może nawet konieczne. Na przykład w aplikacjach interfejsu użytkownika w systemie Windows może znacznie przyspieszyć proces przywracania okna po wywołaniu System.gc () przed zminimalizowaniem okna (szczególnie gdy pozostaje ono zminimalizowane przez dłuższy czas, a części procesu zostają zamienione na dysk).WeakReference
s dla obiektów, które chcesz zatrzymać, jest niepoprawny od samego początku, odśmiecania czy nie. Miałbyś ten sam problem w C ++std::weak_ptr
(choć możesz zauważyć ten problem w wersji C ++ wcześniej niż w wersji Java, ponieważ zniszczenie obiektu nie byłoby odraczane, jak zwykle jest finalizacja).System.gc()
to naprawia, jest obejściem, a nie dobrą praktyką kodowania.Wyjaśniono już, że wywoływanie
system.gc()
może nic nie robić, a każdy kod, który „potrzebuje” modułu wyrzucającego elementy bezużyteczne, jest uszkodzony.Jednak pragmatycznym powodem, dla którego jest to złą praktyką,
System.gc()
jest to, że jest nieefektywne. A w najgorszym przypadku jest to okropnie nieefektywne ! Pozwól mi wyjaśnić.Typowy algorytm GC identyfikuje śmieci, przechodząc przez wszystkie nie-śmieciowe obiekty na stercie, i wnioskując, że każdy obiekt nie odwiedzony musi być śmieci. Na tej podstawie możemy modelować całkowitą pracę śmiecia składa się z jednej części, która jest proporcjonalna do ilości aktualnych danych, i drugiej części, która jest proporcjonalna do ilości śmieci; tj
work = (live * W1 + garbage * W2)
.Załóżmy teraz, że wykonujesz następujące czynności w aplikacji jednowątkowej.
Pierwsze połączenie (przewidujemy)
(live * W1 + garbage * W2)
zadziała i pozbędzie się zaległych śmieci.Drugie połączenie
(live* W1 + 0 * W2)
zadziała i niczego nie odzyska. Innymi słowy, wykonaliśmy(live * W1)
pracę i absolutnie nic nie osiągnęliśmy .Możemy modelować efektywność kolektora jako ilość pracy potrzebnej do zebrania jednostki śmieci; tj
efficiency = (live * W1 + garbage * W2) / garbage
. Aby więc GC była jak najbardziej wydajna, musimy zmaksymalizować wartość,garbage
kiedy uruchamiamy GC; tzn. poczekaj, aż sterty będą pełne. (A także, aby stos był jak największy. Ale to osobny temat.)Jeśli aplikacja nie przeszkadza (przez wywołanie
System.gc()
), GC poczeka do uruchomienia sterty przed uruchomieniem, co spowoduje wydajne zbieranie śmieci 1 . Ale jeśli aplikacja zmusi GC do uruchomienia, istnieje duża szansa, że sterty nie zostaną zapełnione, w wyniku czego śmieci będą zbierane nieefektywnie. Im częściej aplikacja wymusza GC, tym bardziej nieefektywna staje się GC.Uwaga: powyższe objaśnienie przeskakuje nad faktem, że typowy współczesny GC dzieli stertę na „spacje”, GC może dynamicznie rozszerzać stertę, zestaw roboczy aplikacji nie-śmieciowych może się różnić i tak dalej. Mimo to ta sama podstawowa zasada dotyczy wszystkich prawdziwych śmieciarek 2 . Nieefektywne jest zmuszanie GC do uruchomienia.
1 - Tak działa kolektor „przepustowości”. Współbieżne kolektory, takie jak CMS i G1, używają różnych kryteriów, aby zdecydować, kiedy uruchomić moduł odśmiecający.
2 - Wykluczam także menedżerów pamięci, które używają wyłącznie zliczania referencji, ale żadna bieżąca implementacja Java nie używa tego podejścia ... nie bez powodu.
źródło
Wydaje się, że wiele osób mówi ci, abyś tego nie robił. Nie zgadzam się. Jeśli po długim procesie ładowania, takim jak ładowanie poziomu, uważasz, że:
wywołanie System.gc () nie szkodzi. Patrzę na to jak na
inline
słowo kluczowe c / c ++ . To tylko wskazówka dla gc, że ty, deweloper, zdecydowałeś, że czas / wydajność nie jest tak ważna, jak zwykle, i że niektóre z nich można wykorzystać do odzyskania pamięci.Porada, aby nie polegać na robieniu czegokolwiek, jest poprawna. Nie polegaj na tym, że działa, ale wskazanie, że teraz jest odpowiedni czas na zebranie, jest całkowicie w porządku. Wolę tracić czas w punkcie kodu, w którym nie ma to znaczenia (ekran ładowania), niż gdy użytkownik aktywnie wchodzi w interakcję z programem (np. Na poziomie gry).
Jest jeden czas, kiedy będę zmuszać kolekcję: gdy próbuje się dowiedzieć, jest szczególnym przecieki obiektów (zarówno natywny kod lub duże, złożone interakcje zwrotna No i każdy składnik UI, że tyle spojrzeń w Matlab.). To nigdy nie powinno być stosowane w kodzie produkcyjnym.
źródło
stop the world
podejścia, a jeśli tak się stanie, to prawdziwa szkodaLudzie wykonują dobrą robotę, tłumacząc, dlaczego NIE używać, więc powiem ci kilka sytuacji, w których powinieneś go używać:
(Poniższe komentarze dotyczą Hotspot działającego w systemie Linux z modułem zbierającym CMS, w którym jestem pewien, że
System.gc()
w rzeczywistości zawsze wywołuje pełne wyrzucanie elementów bezużytecznych).Po początkowej pracy związanej z uruchomieniem aplikacji możesz być w fatalnym stanie użycia pamięci. Połowa twojego pokolonego pokolenia może być pełna śmieci, co oznacza, że jesteś o wiele bliżej swojego pierwszego CMS. W aplikacjach, w których ma to znaczenie, nie jest złym pomysłem wywołanie System.gc () w celu „zresetowania” sterty do początkowego stanu danych na żywo.
Zgodnie z tymi samymi wierszami co numer 1, jeśli uważnie monitorujesz zużycie sterty, chcesz mieć dokładny odczyt tego, jakie jest twoje podstawowe użycie pamięci. Jeśli pierwsze 2 minuty czasu działania aplikacji to cała inicjalizacja, twoje dane zostaną pomieszane, chyba że wymusisz (hmm ... „zasugerowanie”) pełną gc z góry.
Być może masz aplikację, która jest zaprojektowana tak, aby nigdy nie promować niczego w pokoleniu będącym w posiadaniu, gdy jest uruchomiona. Ale może trzeba zainicjować niektóre dane z góry, które nie są tak duże, aby automatycznie przenieść się do pokrewnej generacji. O ile nie wywołamy System.gc () po skonfigurowaniu wszystkiego, dane mogą znajdować się w nowej generacji, dopóki nie nadejdzie czas na awans. Nagle twoja super-duperowa aplikacja o niskim opóźnieniu i niskiej GC zostaje uderzona OGROMNĄ (względnie rzecz biorąc, oczywiście) opóźnieniem za promowanie tych obiektów podczas normalnych operacji.
Czasami przydaje się udostępnienie wywołania System.gc w aplikacji produkcyjnej do weryfikacji istnienia wycieku pamięci. Jeśli wiesz, że zestaw danych na żywo w czasie X powinien istnieć w pewnym stosunku do zestawu danych na żywo w czasie Y, wówczas przydatne może być wywołanie System.gc () czasu X i czasu Y i porównanie użycia pamięci .
źródło
System.gc()
jednorazowe wywołanie w celu wymuszenia promocji obiektów nic ci nie da. I na pewno nie chcesz dzwonićSystem.gc()
osiem razy z rzędu i modlić się, aby teraz promocja została zakończona, a zaoszczędzone koszty późniejszej promocji uzasadniają koszty wielu pełnych GC. W zależności od algorytmu GC promowanie wielu obiektów może nawet nie ponosić faktycznych kosztów, ponieważ po prostu ponownie przypisuje pamięć do starej generacji lub kopiuje jednocześnie…To bardzo kłopotliwe pytanie i wydaje mi się, że wiele osób sprzeciwia się Javie, pomimo tego, jak użyteczny jest ten język.
Fakt, że nie można ufać, że „System.gc” zrobi cokolwiek, jest niezwykle zniechęcający i łatwo wywołuje w języku uczucie „strachu, niepewności, wątpliwości”.
W wielu przypadkach miło jest radzić sobie ze skokami pamięci, które celowo wywołujesz, zanim nastąpi ważne zdarzenie, które sprawi, że użytkownicy będą myśleć, że Twój program jest źle zaprojektowany / nie odpowiada.
Umiejętność kontrolowania wyrzucania elementów bezużytecznych byłaby bardzo doskonałym narzędziem edukacyjnym, co z kolei poprawiłoby zrozumienie ludzi, jak działa wyrzucanie elementów bezużytecznych i jak programy wykorzystują to zachowanie domyślne i kontrolowane.
Pozwól mi przejrzeć argumenty tego wątku.
Często program może nic nie robić i wiesz, że nic nie robi ze względu na sposób, w jaki został zaprojektowany. Na przykład może to być coś w rodzaju długiego oczekiwania z dużym oknem komunikatu oczekiwania, a na końcu równie dobrze może dodać wezwanie do zbierania śmieci, ponieważ czas jego uruchomienia zajmie naprawdę niewielki ułamek czasu długo czekać, ale pozwoli uniknąć działania gc w trakcie ważniejszej operacji.
Nie zgadzam się, nie ma znaczenia, jaki posiadasz śmieci. Jego zadaniem jest śledzenie śmieci i ich czyszczenie.
Dzwoniąc do gc w czasach, gdy użycie jest mniej krytyczne, zmniejszasz prawdopodobieństwo jego uruchomienia, gdy twoje życie zależy od uruchomionego określonego kodu, ale zamiast tego decyduje się na zbieranie śmieci.
Jasne, może nie zachowywać się tak, jak tego chcesz lub się spodziewasz, ale kiedy chcesz to nazwać, wiesz, że nic się nie dzieje, a użytkownik jest skłonny tolerować spowolnienie / przestoje. Jeśli plik System.gc działa, świetnie! Jeśli nie, przynajmniej spróbowałeś. Po prostu nie ma wad, chyba że śmieciarz ma nieodłączne skutki uboczne, które powodują coś okropnie nieoczekiwanego w stosunku do zachowania się śmieciarza, jeśli zostanie wywołany ręcznie, a to samo w sobie powoduje brak zaufania.
Jest to przypadek użycia, który nie może być osiągnięty w sposób niezawodny, ale mógłby mieć miejsce, gdyby system został zaprojektowany w ten sposób. To tak, jakby zrobić sygnalizację świetlną i sprawić, aby niektóre / wszystkie przyciski sygnalizacji świetlnej nic nie robiły. To sprawia, że zastanawiasz się, dlaczego ten przycisk jest na początek, javascript nie ma funkcji usuwania śmieci, więc nie nie analizuj tego za to.
co to jest „wskazówka”? co to jest „ignorować”? komputer nie może po prostu przyjmować wskazówek ani niczego ignorować, istnieją ścisłe ścieżki zachowania, które mogą być dynamiczne, które są kierowane intencją systemu. Prawidłowa odpowiedź obejmowałaby to, co tak naprawdę robi śmieciarz, na poziomie implementacji, co powoduje, że nie wykonuje on zbierania danych na żądanie. Czy ta funkcja jest po prostu niedostępna? Czy są jakieś warunki, które muszę spełnić? Jakie są te warunki?
W tej chwili GC Javy często wygląda jak potwór, któremu po prostu nie ufasz. Nie wiesz, kiedy to przyjdzie lub odejdzie, nie wiesz, co się stanie, jak to zrobi. Mogę sobie wyobrazić, że niektórzy eksperci mają lepsze pojęcie o tym, jak działa ich odśmiecanie według instrukcji, ale zdecydowana większość po prostu ma nadzieję, że „po prostu działa”, i że trzeba ufać nieprzejrzystemu algorytmowi, który wykona pracę dla ciebie, jest frustrujący.
Istnieje duża luka między czytaniem o czymś lub uczeniem się czegoś, a faktycznym widzeniem jego realizacji, różnicami między systemami i możliwością grania bez konieczności patrzenia na kod źródłowy. To stwarza pewność siebie i poczucie opanowania / zrozumienia / kontroli.
Podsumowując, istnieje nieodłączny problem z odpowiedziami: „ta funkcja może nic nie robić i nie będę wchodził w szczegóły, jak powiedzieć, kiedy coś robi, a kiedy nie, i dlaczego nie zrobi lub nie, często sugeruje, że próba zrobienia tego jest po prostu sprzeczna z filozofią, nawet jeśli intencja jest uzasadniona ”.
Może być w porządku, aby Java GC zachowywała się w ten sposób, lub nie, ale aby to zrozumieć, trudno jest naprawdę podążać w jakim kierunku, aby uzyskać kompleksowy przegląd tego, co możesz zaufać GC i nie robić, więc zbyt łatwo jest po prostu nie ufać językowi, ponieważ celem języka jest kontrolowane zachowanie do filozoficznego stopnia (dla programisty, szczególnie początkującego, łatwo popadnie w kryzys egzystencjalny z powodu pewnych zachowań systemowych / językowych) są w stanie tolerować (a jeśli nie możesz, po prostu nie będziesz używać języka, dopóki nie będziesz musiał), a więcej rzeczy, których nie możesz kontrolować bez żadnego znanego powodu, dla którego nie możesz ich kontrolować, jest z natury szkodliwe.
źródło
Wydajność GC opiera się na szeregu heurystyk. Na przykład powszechna heurystyka polega na tym, że dostęp do zapisu obiektów występuje zwykle na obiektach, które zostały utworzone niedawno. Innym jest to, że wiele obiektów jest bardzo krótkotrwałych (niektóre będą używane przez długi czas, ale wiele zostanie odrzuconych kilka mikrosekund po ich utworzeniu).
Dzwonienie
System.gc()
jest jak kopanie GC. Oznacza to: „wszystkie te dokładnie dostrojone parametry, te inteligentne organizacje, cały wysiłek włożony w przydzielanie i zarządzanie obiektami w taki sposób, aby wszystko szło gładko, no cóż, po prostu zrzuć wszystko i zacznij od zera”. To może zwiększyć wydajność, ale przez większość czasu to tylko pogarsza osiągi.Aby korzystać
System.gc()
niezawodnie (*), musisz wiedzieć, jak działa GC we wszystkich jego drobnych szczegółach. Takie szczegóły mogą się nieco zmienić, jeśli używasz JVM od innego dostawcy lub następnej wersji od tego samego dostawcy lub tego samego JVM, ale z nieco innymi opcjami wiersza polecenia. Dlatego rzadko jest to dobry pomysł, chyba że chcesz rozwiązać konkretny problem, w którym kontrolujesz wszystkie te parametry. Stąd pojęcie „złej praktyki”: nie jest to zabronione, metoda istnieje, ale rzadko się opłaca.(*) Mówię tutaj o wydajności.
System.gc()
nigdy nie zepsuje poprawnego programu Java. Nie wyczaruje dodatkowej pamięci, której JVM nie mógłby uzyskać inaczej: przed wyrzuceniemOutOfMemoryError
, JVM wykonuje zadanieSystem.gc()
, nawet jeśli w ostateczności.źródło
Czasami ( nie często! ) Naprawdę wiesz więcej na temat przeszłego, obecnego i przyszłego wykorzystania pamięci niż czas działania. Nie zdarza się to zbyt często i twierdziłbym, że nigdy w aplikacji internetowej, gdy są obsługiwane normalne strony.
Wiele lat temu pracowałem nad generatorem raportów
Po pierwsze, ponieważ nie był to czas rzeczywisty, a użytkownicy oczekiwali na zgłoszenie, opóźnienie w uruchomieniu GC nie stanowiło problemu, ale musieliśmy tworzyć raporty w tempie szybszym niż oczekiwano.
Patrząc na powyższy zarys procesu, jasne jest, że.
Dlatego wyraźnie warto było wykonywać GC, gdy kolejka żądań była pusta; nie było w tym żadnych wad.
Może warto wykonać test GC po wysłaniu każdego raportu pocztą e-mail, ponieważ wiemy, że jest to dobry czas na test GC. Jeśli jednak komputer ma wystarczającą ilość pamięci RAM, lepsze wyniki można uzyskać, opóźniając uruchomienie GC.
To zachowanie zostało skonfigurowane dla poszczególnych instalacji, dla niektórych klientów włączenie wymuszonej GC po każdym raporcie znacznie przyspieszyło ochronę raportów. (Spodziewam się, że było to spowodowane niską pamięcią na serwerze i działaniem wielu innych procesów, dlatego też wymuszone GC zredukowało stronicowanie.)
Nigdy nie wykryliśmy, że instalacja, która nie przyniosła korzyści, była wymuszonym uruchomieniem GC za każdym razem, gdy kolejka robocza była pusta.
Ale, powiedzmy jasno, powyższe nie jest częstym przypadkiem.
źródło
Może piszę kiepski kod, ale zdałem sobie sprawę, że kliknięcie ikony kosza na IDE zaćmienia i siatki jest „dobrą praktyką”.
źródło
System.gc()
okresowego wywoływania , prawdopodobnie byłoby to denerwujące.Po pierwsze, istnieje różnica między specyfikacją a rzeczywistością. Specyfikacja mówi, że System.gc () jest wskazówką, że GC powinien uruchomić, a maszyna wirtualna może go zignorować. W rzeczywistości maszyna wirtualna nigdy nie zignoruje wywołania System.gc ().
Dzwonienie do GC wiąże się z nietrywialnym kosztem połączenia, a jeśli zrobisz to w przypadkowym momencie, prawdopodobnie nie zobaczysz nagrody za swoje wysiłki. Z drugiej strony, naturalnie wywołana kolekcja najprawdopodobniej zwróci koszty połączenia. Jeśli masz informacje wskazujące, że należy uruchomić GC, możesz zadzwonić do System.gc () i powinieneś zobaczyć korzyści. Jednak z mojego doświadczenia wynika, że dzieje się tak tylko w kilku przypadkach, ponieważ jest bardzo mało prawdopodobne, że będziesz mieć wystarczającą ilość informacji, aby zrozumieć, czy i kiedy należy wywołać System.gc ().
Jeden z wymienionych tutaj przykładów, uderzanie w kosz na śmieci w twoim IDE. Jeśli idziesz na spotkanie, dlaczego by nie trafić? Koszty ogólne nie będą miały na ciebie wpływu, a sterty mogą zostać oczyszczone po powrocie. Zrób to w systemie produkcyjnym, a częste wezwania do odbioru zatrzymają go! Nawet okazjonalne połączenia takie jak te wykonywane przez RMI mogą zakłócać wydajność.
źródło
Tak, wywołanie System.gc () nie gwarantuje, że się uruchomi, jest to zapytanie do JVM, które można zignorować. Z dokumentów:
Nazywanie go prawie zawsze jest złym pomysłem, ponieważ automatyczne zarządzanie pamięcią zwykle wie lepiej niż ty, kiedy masz gc. Dzieje się tak, gdy w wewnętrznej puli wolnej pamięci jest mało lub jeśli system operacyjny zażąda zwrotu części pamięci.
Dopuszczalne może być wywołanie System.gc (), jeśli wiesz, że to pomaga. Rozumiem przez to, że dokładnie przetestowałeś i zmierzyłeś zachowanie obu scenariuszy na platformie wdrażania , i możesz pokazać, że to pomaga. Pamiętaj jednak, że gc nie jest łatwo przewidywalny - może pomóc w jednym biegu, a zaszkodzić w innym.
źródło
Z mojego doświadczenia wynika, że używanie System.gc () jest efektywną formą optymalizacji specyficzną dla platformy (gdzie „platforma” to kombinacja architektury sprzętowej, systemu operacyjnego, wersji JVM i możliwych większej liczby parametrów środowiska wykonawczego, takich jak dostępna pamięć RAM), ponieważ jej zachowanie, chociaż z grubsza przewidywalne na konkretnej platformie, może (i będzie) znacznie się różnić między platformami.
Tak, są sytuacje, w których System.gc () poprawi (postrzega) wydajność. Na przykład, jeśli opóźnienia są dopuszczalne w niektórych częściach twojej aplikacji, ale nie w innych (przykład gry cytowany powyżej, w którym chcesz, aby GC miało miejsce na początku poziomu, a nie na poziomie).
Jednak to, czy to pomoże, czy skrzywdzi (lub nic nie zrobi), zależy w dużej mierze od platformy (jak zdefiniowano powyżej).
Myślę więc, że jest to poprawna optymalizacja specyficzna dla platformy w ostateczności (tzn. Jeśli inne optymalizacje wydajności nie są wystarczające). Ale nigdy nie powinieneś tego nazywać tylko dlatego, że uważasz, że to może pomóc (bez określonych testów porównawczych), ponieważ są szanse, że nie będzie.
źródło
Ponieważ obiekty są przydzielane dynamicznie za pomocą nowego operatora,
możesz się zastanawiać, jak takie obiekty są niszczone i ich
pamięć zwalniana w celu późniejszego ponownego przydzielenia.
W niektórych językach, takich jak C ++, dynamicznie przydzielane obiekty muszą być ręcznie zwalniane za pomocą operatora delete.
źródło