2013-04-16 17 views
5

Zastanawiam się, czy uważasz za dobrą praktykę usuwanie odwołań (ustawiając je na null) do obiektów, aby pomóc narzędziu Java Garbage Collector.Czy dobrą praktyką jest usuwanie odniesień, aby pomóc GC?

Na przykład załóżmy, że masz klasę z dwoma polami, z których jeden jest bardzo zajęty. Jeśli wiesz, że potrzebujesz go tylko do konkretnego przetwarzania, możesz je natychmiast anulować, aby pomóc GC.

Załóżmy, że naprawdę potrzebuję tych dwóch pól, a nie tylko zmiennych wewnętrznych, więc heavyObject1 nie może być poza zakresem na końcu metody.

Czy zrobiłbyś to jako ogólną praktykę?

public class TestClass { 

    public static Object heavyObject1; 
    public static Object object2; 

    private static void action() { 
    object2 = doSomething(heavyObject1); 

    heavyObject1 = null; //is this good? 
    } 
} 
+0

Problem z takim zachowaniem polega na tym, że jest on niezgodny z polami końcowymi, przez co trudniej jest zabezpieczyć kod. – SpaceTrucker

+0

"Dereferencja" oznacza pobranie rzeczy, do której się odwołuje. Edytowałem i zmieniłem to. – delnan

Odpowiedz

8

Zazwyczaj nie jest to konieczne.

To dobry pomysł na poniższym konkretnej sytuacji:

  • Obiekt jest duży (tj wystarczająco dużą, aby dbać)
  • Jesteś pewien przedmiot nie będą znowu potrzebne
  • przedmiotem nie wyjdzie z zakresu inaczej (np wiesz otaczającą obiekt nie być garbage zebrane)

Jednak jeśli znajdujesz się w tej sytuacji, to podejrzewam, że masz zapach wzornictwa: dlaczego obiekt wewnętrzny ma taki inny zakres/czas życia od otaczającego obiektu? To sprawia, że ​​jestem podejrzliwy, ponieważ zazwyczaj, gdy tworzysz wykres obiektów z kompozycją, spodziewasz się, że złożone obiekty będą miały podobne okresy życia.

0

To z pewnością nie złą praktyką przypisać null do referencji, jeśli nie chcesz korzystać z tego obiektu więcej. Jednak jest to zła praktyka polegająca na liczeniu na GC, aby je odebrać w dowolnym momencie wkrótce lub w ogóle podczas wykonywania programu.

0

Nie, to niepotrzebne. Gdy tylko heavyObject1 znajdzie się poza zakresem, i tak zostanie oznaczony jako GC.

+2

Jeśli jest to pole, nie zniknie z zakresu, dopóki nie zniknie obiekt, w którym się znajduje. –

2

W większości przypadków nie trzeba ustawiać obiektu na wartość null, aby można było pobrać śmieci. Jeśli odkażesz obiekt w odpowiednim zakresie (poziom metody, poziom instancji lub poziom klasy), obiekt będzie nieosiągalny natychmiast po jego użyciu i będzie kwalifikował się do usuwania śmieci.

+0

'heavyObject1' nie może wyjść poza zasięg, dopóki' TestClass' nie wykracza poza zakres, ponieważ jest polem. – Alphaaa

+1

Prawidłowe ... Ale jeśli czujesz potrzebę, aby było ono zerowe, oznacza to, że zakres ciężkiego obiektu1 nie został poprawnie zdefiniowany. Powinien być na poziomie instancji lub poziomie metody. – JRR

0

Jako ogólna , nie, ponieważ nie jest potrzebna.

Są specjalne przypadki - mogę sobie wyobrazić na przykład długą klasę, która ma długą listę obiektów zużywających pamięć, z którymi robi coś raz, a następnie czeka na jakiś czas, zanim zastąpi tę listę innym lista. Może również null na liście, gdy czekasz, nic nie zaszkodzi, i może uniemożliwić program z konieczności do obu list w tym samym czasie.

Ale w tym miejscu znów obowiązuje zasada "niepotrzebna".Nie można liczyć na uruchamianie GC w określonym czasie, dlatego program musi obsługiwać jednoczesne posiadanie obu list na stercie, aby program ten nie działał, gdyby tak nie było.

I PROSZĘ nie zachęcać ludzi do robienia "reguły" w tej sprawie. Kiedy myślę o całym kodzie, który czytałem, gdzie ktoś kładzie "końcowy" przed (prawie) wszystkimi zmiennymi, które (jak sądzą) nie zmienią się po inicjalizacji, sprawiają, że kod jest mniej czytelny i przekonuje mnie, że programista brak zrozumienia poprawy szybkości, którą rzekomo tworzyli ...

0

Nie. Zasadniczo dobrą praktyką jest stosowanie pól lub miejscowych.

W większości przypadków obiekt, którego pole zostanie usunięte, stanie się nieosiągalny przed uruchomieniem GC. Jeśli tak się stanie, cykle procesora, które zużyłeś, zerując pole obiektu, zostaną zmarnowane.

Jedyne sytuacje, w których konieczne jest/dobrze do null pól/Miejscowi są gdzie:

  1. jest prawdopodobne że obiekt nadrzędny nadal będzie osiągalny, gdy biegnie GC I
  2. obiekt podrzędny (wykres) jest wystarczająco duży, aby ilość pamięci zachowanej była znacząca ... w stosunku do całkowitego rozmiaru sterty.

Można też to zrobić, jeśli realizują klasy, która jest przeznaczone który ma być używany w szerokim zakresie sytuacji ... i niektóre z tych sytuacji zmieściłoby powyższe kryteria. (Na przykład implementacja struktury danych, w której instancje mogą być duże).

0

Obiekty dereferencyjne są zbędne, chyba że twoja klasa zarządza własną pamięcią lub twoja klasa buforuje zasoby, wtedy przestarzałe referencje powinny zostać wyeliminowane.

Powiązane problemy