2014-12-25 2 views
0

Есть ли способ проверить количество ссылок на объект Java?Число ссылок на объект Java

Пусть myObject будет ссылкой на объект, и объект уже выполнил его работу. Я готовлю его умереть в методе утилизации, и я собираюсь использовать ссылку myObject для некоторых других целей, поэтому сборщик мусора можно убить. Но я не уверен, что никаких других ссылок на объект нет. Как это проверить?

+1

Почему это имеет значение? Вам не нужно явно указывать «нулевые» экземпляры, когда они недоступны, они имеют право * быть собранными мусором (когда или если они будут собирать мусор, это не указано). –

+0

Предположим, что я собираюсь использовать myObject для некоторых других целей. Я немного перефразирую вопрос. –

+1

Нет. Я все еще не совсем понимаю, вы ищете ['WeakReference'] (http://docs.oracle.com/javase/7/docs/api/java/lang/ref/WeakReference.html) ? –

ответ

0

Как указано в комментариях, вы почти наверняка не хотите/должны знать количество ссылок на объект. Преимущество сборки мусора состоит в том, что одна часть вашей программы может обнулить ссылки на объект, не заботясь о том, сохраняет ли другая часть программы ссылки на объект.

Если вы хотите знать, когда объект был собран, то держите WeakReference ему, как сказал Эллиот Фриш в комментариях - если reference.get() возвращает null, то объект был собран мусором. Более грубой альтернативой является переопределение метода объекта finalize и запись журнала при его вызове.

Если вы считаете, что у вас есть утечка памяти, используйте Eclipse memory analyzer или другой инструмент для анализа/профилирования памяти.

Если вам действительно нужно знать количество ссылок, принадлежащих объекту, то единственным решением, которое я могу придумать, является использование Jikes RVM - у него есть набор инструментов для управления памятью, который включает в себя сборщики подсчета ссылок с коллекцией резервного цикла, вы должны иметь возможность подключаться к сборщику для определения количества ссылок, удерживаемых объектом (после запуска коллектора циклов резервного копирования, если вы не уверены, что объект не содержит переходную ссылку на себя). Использование RVM не является тривиальной задачей; Кроме того, вы не должны использовать RVM в производственной среде - это строго исследовательский инструмент.

Вы также можете попробовать хакерство вместе что-то вроде следующего

public class Wrapper<T> { 
    private WeakReference<T> thisReference; 
    private ConcurrentLinkedQueue<WeakReference<Object>> references = 
    new ConcurrentLinkedQueue<>(); 

    public T getObject(Object obj) { 
    T thisObject = thisReference.get(); 
    if(thisObject != null) { 
     references.offer(new WeakReference(obj)); 
    } 
    return thisObject; 
    } 

    public int referenceCount() { 
    if(thisReference.get() == null) { 
     references.clear(); 
     return 0; 
    } else { 
     Iterator<WeakReference<Object>> iterator = references.iterator(); 
     while(iterator.hasNext()) { 
     WeakReference<Object> reference = iterator.next(); 
     if(reference.get() == null) { 
      iterator.remove(); 
     } 
     } 
     return references.size(); 
    } 
    } 
} 

Идеи заключается в том, чтобы заставить объекты получить ссылку на объект с помощью getObject, который регистрирует WeakReference к приобретающему объекту. referenceCount затем подсчитает количество этих WeakReferences, которые не являются нулевыми. Это проще, но не так точно, как использование подлинного счетного коллектора с помощью Jikes, потому что в коллекции references может быть недопустимым WeakReferences, которые еще не были собраны в мусор и поэтому являются не нулевыми; там также ничего не мешает экранированному thisObject быть переданным другому объекту, который не был зарегистрирован через getObject. Это также вводит новую проблему, у кого есть ссылка на Wrapper, поэтому я не уверен, что это принесет вам что угодно. Суть в том, что точный подсчет ссылок должен выполняться на уровне виртуальной машины (т. Е. Jikes), а не в коде пользователя.

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