2016-12-10 4 views
0

Я немного смущен использованием фантомных ссылок. Я читал, что когда Object, который имеет только ссылку Phantom, указывающую их, можно собирать всякий раз, когда коллекционеру мусора нравится это. Но в моем примере это не работает должным образом.Ссылка на фантом не освобождена во время GC

import java.lang.ref.PhantomReference; 
import java.lang.ref.Reference; 
import java.lang.ref.ReferenceQueue; 
import java.util.HashMap; 
import java.util.Map; 


public class ClassTest { 
    private static Thread m_collector; 
    private static boolean m_stopped = false; 
    private static final ReferenceQueue refque = new ReferenceQueue(); 
    Map<Reference,String> cleanUpMap = new HashMap<Reference,String>(); 


    public void startThread() { 
     m_collector = new Thread() { 
      public void run() { 
       while (!m_stopped) { 
        try { 
          Reference ref = refque.remove(1000); 
          System.out.println(" Timeout "); 
               if (null != ref) { 
          System.out.println(" ref not null "); 

         } 
        } catch (Exception ex) { 
         break; 
        } 
       } 
      } 
     }; 
     m_collector.setDaemon(true); 
     m_collector.start(); 
    } 

    public void register() { 
     System.out.println("Creating phantom references"); 

     class Referred { 
       } 

      Referred strong = new Referred(); 
      PhantomReference<Referred> pref = new PhantomReference(strong, refque); 
    // cleanUpMap.put(pref, "Free up resources"); 
      strong = null; 

    } 



public static void collect() throws InterruptedException { 
    System.out.println("GC called"); 
    System.gc(); 
    System.out.println("Sleeping"); 
    Thread.sleep(5000); 
} 

public static void main(String args[]) throws InterruptedException { 
    ClassTest test= new ClassTest(); 
    test.startThread(); 

    test.register(); 
    test.collect(); 
    m_stopped = true; 
    System.out.println("Done"); 
} 

} 

В приведенном выше примере, когда я запускаю, я вижу, что объект «сильный» не является мусором, собираемым автоматически. Я ожидал, что объект получит сбор мусора автоматически, когда «сильному» объекту присваивается значение null. Как ни странно, это сбор мусора, только когда я раскомментирую следующую строку в функции register.

//cleanUpMap.put(pref, "Free up resources");" 

В чем причина этого? Но, если я создаю фантомную ссылку в самой главной функции, эта проблема не возникает. Другими словами, объект - это сбор мусора автоматически, когда «сильный» присваивается null внутри основной функции, как в следующем коде.

public static void main(String args[]) throws InterruptedException { 
    System.out.println("Creating phantom references"); 

    // The reference itself will be appended to the dead queue for clean up. 
    ReferenceQueue dead = new ReferenceQueue(); 

    PhantomReference<Referred> phantom = new PhantomReference(strong, dead); 


    strong = null; 

    // The object may now be collected 
    System.out.println("Suggesting collection"); 
    System.gc(); 
    System.out.println("Sleeping"); 
    Thread.sleep(5000); 

    // Check for 
    Reference reference = dead.poll(); 
    if (reference != null) { 
     System.out.println("not null"); 
    } 
    System.out.println("Done"); 
} 

Почему поведение отличается от обоих сценариев?

+1

Возможный дубликат [Нужно ли поддерживать сильную ссылку на WeakReference, который используется только для выполнения финализации?] (Http://stackoverflow.com/questions/32108427/do-i-need-to-keep- a-strong-reference-to-a-weakreference-that-is-only-used-to-per) – the8472

ответ

1

Ваш фантомный справочник - обычный объект Java, и это будет сбор мусора, если он недоступен.

Если ссылка на фантом собрана до или в той же коллекции, что и объект ссылки, она не будет добавлена ​​в очередь ссылок.

Размещение всех фантомных ссылок на коллекцию предотвращает преждевременную сбор мусора.

Обычно вам нужна специальная коллекция необработанных фантомных ссылок вместе со ссылочной очередью.

Вы можете найти пример внедрения флеш-памяти на основе post mortem в this article.

+0

вы можете посмотреть http://stackoverflow.com/q/41396476/2674303. – gstackoverflow

Смежные вопросы