powered by simpleCommunicator - 2.0.61     © 2026 Programmizd 02
Целевая тема:
Создать новую тему:
Автор:
Закрыть
Цитировать
Форумы / Java [игнор отключен] [закрыт для гостей] / phantom reference vs weak reference
48 сообщений из 48, показаны все 2 страниц
phantom reference vs weak reference
    #39377575
questioner
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Прочитал n-ое количество топиков на эту тему, но видимо моего чувства английского не достаточно, чтобы уловить эту тонкую разницу.

На данный момент понятно, что
- PhantomReference слабее, чем WeakReference
-Судя по всему разница как-то завязана на исполнение метода finalize и помещении в очередь ReferenceQueue.

Также замечено, что у WeakReference и SoftReference есть 2 конструктора: с очередью и без очереди ReferenceQueue, что контрастирует с PhantomReference, который имеет единственный конструктор с очередью.

Разница phantom и weak в том, что в случае weak:
1.gc видит, что пора собрать объект
2.помещает ссылку на него в очередь
3.вызывает finalize
4.память, которую занимал объект высвобождается.

в случае phantom:
1.gc видит, что пора собрать объект
2.вызывает finalize
3.память, которую занимал объект высвобождается.
4.помещает ссылку на него в очередь

это происходит в несколько заходов gc(не понял почему, надеюсь это не так важно)
При этом зачем-то упоминается, что объект можно спасти если в finalize создать strong ссылку на объект.


Не очень понятно зачем эта очередь. всё что нарыл:

http://www.quizful.net/post/java_reference_types когда объект доступный с помощью ссылки удаляется, то сам объект ссылки становится доступным в очереди ReferenceQueue. Этот механизм позволяет удалять пустые ссылки.
это что для случаев когда вообще нужно когда каждый бит экономить?
Как пустую ссылку удалить вообще?
пустая ссылка эта та, что в null ведь ведет?
Сам факт передачи аргумента ReferenceQueue заставит gc почистить память, которую занимает ссылка или это просто инструмент для нас отслеживать жизненный цикл объекта/ссылки?

P.S. понимаю, что это поток мыслей, но яснее выразить вопросы не получается
...
Рейтинг: 0 / 0
phantom reference vs weak reference
    #39377603
Фотография Blazkowicz
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Для начала я предлагаю разделить вопросы. PhantomReference вообще отдельная тема. На сколько я помню, его нельзя использовать без ReferenceQueue. А предназначен он для очискти нативных ресурсов. Хорошие примеры использования можно поискать в исходниках JDK. Кажется, с помощью него чистят нативную память под VolatileImage. То есть это более эффективная замена finalize.

WeakReference и SoftReference более похожи. У них просто разное поведение, но схожее использование.
...
Рейтинг: 0 / 0
phantom reference vs weak reference
    #39377609
Alexey Tomin
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
questioner http://www.quizful.net/post/java_reference_types когда объект доступный с помощью ссылки удаляется, то сам объект ссылки становится доступным в очереди ReferenceQueue. Этот механизм позволяет удалять пустые ссылки.

Насколько я понимаю коммент к ReferenceQueue, то в эту очередь объект попадает, когда GC обнаружил, что объект может быть удалён, а не когда он удаляется.
Например, если этот объект- список, то может имеет смысл чистить списки в этой очереди- элементы из списка могут быть собраны раньше.
...
Рейтинг: 0 / 0
phantom reference vs weak reference
    #39377638
questioner
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
BlazkowiczWeakReference и SoftReference более похожи. У них просто разное поведение, но схожее использование.

Тут то всё предельно понятно. Везде одинаково пишут, что объекты на которые ссылаются SoftReference вероятно будут удалены только при нехватке памяти, WeakReference - тогда, когда будет удобно gc.


BlazkowiczНа сколько я помню, его нельзя использовать без ReferenceQueue
я об этом писал.
meзамечено, что у WeakReference и SoftReference есть 2 конструктора: с очередью и без очереди ReferenceQueue, что контрастирует с PhantomReference, который имеет единственный конструктор с очередью.

непонятно зачем эта очередь вообще нужна.

Alexey Tomin Насколько я понимаю коммент к ReferenceQueue, то в эту очередь объект попадает, когда GC обнаружил, что объект может быть удалён, а не когда он удаляется.

для soft/weak да, для phantom судя по всему нет. Ну во всяком случае в соответсвии с тем, что я вычитал

Alexey Tomin Например, если этот объект- список, то может имеет смысл чистить списки в этой очереди- элементы из списка могут быть собраны раньше.
не понял примера

BlazkowiczТо есть это более эффективная замена finalize.

Тут у нас речь идёт про phantom ссылки, получается это пост-finalize такой?
в чем большая эффективность?
...
Рейтинг: 0 / 0
phantom reference vs weak reference
    #39377641
questioner
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
finalize же всё равно будет вызван
...
Рейтинг: 0 / 0
phantom reference vs weak reference
    #39377660
Фотография Blazkowicz
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
questionerfinalize же всё равно будет вызван
Просто поищи в гугле. Статей на эту тему 100500. Одна из основных причин - finalize тормозной.
...
Рейтинг: 0 / 0
phantom reference vs weak reference
    #39377674
questioner
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Blazkowiczquestionerfinalize же всё равно будет вызван
Просто поищи в гугле. Статей на эту тему 100500. Одна из основных причин - finalize тормозной.

Ок. Наверное понял. Это наша задача использовать либо finalize либо использовать фантомные ссылки.

Пока самое неясное это предназначение ReferenceQueue. Для фантомных ссылок эта очередь имеет особое значение судя по всему
...
Рейтинг: 0 / 0
phantom reference vs weak reference
    #39377678
Alexey Tomin
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
questionerДля фантомных ссылок эта очередь имеет особое значение судя по всему

Вычистить данные из native-памяти, к примеру.
...
Рейтинг: 0 / 0
phantom reference vs weak reference
    #39377685
questioner
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Alexey TominquestionerДля фантомных ссылок эта очередь имеет особое значение судя по всему

Вычистить данные из native-памяти, к примеру.

она ж null возвращает всегда для фантомных ссылок
...
Рейтинг: 0 / 0
phantom reference vs weak reference
    #39377690
questioner
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
зачем вообще очередь? чтобы передавать её в несколько конструкторов?
...
Рейтинг: 0 / 0
phantom reference vs weak reference
    #39377715
забыл ник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
questionerзачем вообще очередь? чтобы передавать её в несколько конструкторов?

http://samolisov.blogspot.com.by/2011/09/phantomreferences-java.html

Я наверное понял что вас смущает. Ваш вопрос сводится к тому - зачем нужна очередь, если теоретически можно добавить метод isCollected в тот же PhantomReference. Ответ состоит в том, что поток выполняющий ваш код и поток сборки мусора это два разных потока, которые могут увидеть одну и ту же переменную в разном состоянии(data race), а так как очистка объекта это не атомарное действие(надо вызвать как finalise так и физически очистить память от байтов и тд), то использовать PhantomReference опасно, так как finalise уже отработал а память физически не удалилась и тд. Поэтому вводится третий объект очередь, который правильно синхронизирован, и если метод poll вернул что-то - значит все действия по очистке ГАРАНТИРОВАННО завершились - и вы можете приступать к кастомной очистке, как-то так.
...
Рейтинг: 0 / 0
phantom reference vs weak reference
    #39377850
questioner
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
забыл никquestionerзачем вообще очередь? чтобы передавать её в несколько конструкторов?

http://samolisov.blogspot.com.by/2011/09/phantomreferences-java.html

Я наверное понял что вас смущает. Ваш вопрос сводится к тому - зачем нужна очередь, если теоретически можно добавить метод isCollected в тот же PhantomReference. Ответ состоит в том, что поток выполняющий ваш код и поток сборки мусора это два разных потока, которые могут увидеть одну и ту же переменную в разном состоянии(data race), а так как очистка объекта это не атомарное действие(надо вызвать как finalise так и физически очистить память от байтов и тд), то использовать PhantomReference опасно, так как finalise уже отработал а память физически не удалилась и тд. Поэтому вводится третий объект очередь, который правильно синхронизирован, и если метод poll вернул что-то - значит все действия по очистке ГАРАНТИРОВАННО завершились - и вы можете приступать к кастомной очистке, как-то так.

Об этом я не думал пока, но спасибо, буду знать.

Меня не то, чтобы что-то смущало, я понять хочу))


Вот написал я такой код скажем:

Код: java
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
22.
public class Main {

    public static void main(String[] args) throws InterruptedException {
        ReferenceQueue<Bar> objectReferenceQueue = new ReferenceQueue<>();
        PhantomReference<Bar> phantomReference = new PhantomReference<Bar>(new Bar(), objectReferenceQueue);
        while (true){
            System.out.println(objectReferenceQueue.poll());
            System.out.println(phantomReference.get());
            Thread.sleep(500);
        }
    }
}

class Bar {
    int counter = 0;

    @Override
    public void finalize() throws Throwable {
        System.out.println("finalize");
        super.finalize();
    }
}



он выводит
null
null
null
null
....


Зачем так сложно писать null ?
...
Рейтинг: 0 / 0
phantom reference vs weak reference
    #39377859
Фотография Blazkowicz
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
questionerЗачем так сложно писать null ?
System.gc(); добавь. В цикл, например.
...
Рейтинг: 0 / 0
phantom reference vs weak reference
    #39377892
questioner
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
BlazkowiczquestionerЗачем так сложно писать null ?
System.gc(); добавь. В цикл, например.

Да, поведение изменилось.

Код: java
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
22.
23.
24.
25.
26.
27.
28.
public class Main {

    public static void main(String[] args) throws InterruptedException {
        ReferenceQueue<Bar> objectReferenceQueue = new ReferenceQueue<>();
        PhantomReference<Bar> phantomReference = new PhantomReference<Bar>(new Bar(), objectReferenceQueue);
        while (true) {
            Reference<? extends Bar> reference = objectReferenceQueue.poll();
            System.out.println("poll(): " + reference);
            if (reference != null) {
                System.out.println("poll().get(): " + reference.get());
                return;
            }

            System.gc();
            Thread.sleep(500);
        }
    }
}

class Bar {
    int counter = 777;

    @Override
    public void finalize() throws Throwable {
        System.out.println("finalize");
        super.finalize();
    }
}



теперь вывод:

авторpoll(): null
finalize
poll(): null
poll(): java.lang.ref.PhantomReference@14ae5a5
poll
().get(): null

хотя в дебаггере в поле referent я вижу объект Bar:

...
Рейтинг: 0 / 0
phantom reference vs weak reference
    #39377898
Фотография Blazkowicz
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
questionerхотя в дебаггере в поле referent я вижу объект Bar:

Это вопрос или констатация факта?
http://stackoverflow.com/questions/7048767/why-are-phantom-references-not-cleared-as-they-are-enqueued
...
Рейтинг: 0 / 0
phantom reference vs weak reference
    #39377905
questioner
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
BlazkowiczЭто вопрос или констатация факта?


Это констатация непонимания факта, с надеждой на получение объяснения.
...
Рейтинг: 0 / 0
phantom reference vs weak reference
    #39377908
questioner
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Blazkowicz,


авторPhantom references are not cleared when enqueued
вот я не понимаю, что понимается под cleared и под enqueued?

enqueued это попадание в ту самую ReferenceQueue ?
...
Рейтинг: 0 / 0
phantom reference vs weak reference
    #39377921
Фотография Blazkowicz
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
questioner,

Да, enqueue - это постановка в ReferenceQueue, а cleared, вероятно, фактическое удаление объекта из кучи.
...
Рейтинг: 0 / 0
phantom reference vs weak reference
    #39377924
questioner
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Blazkowicz,

Получается для weak и soft попадание в очередь это фактически очистка из кучи, а для phantom это событие, когда можно явно очистить из кучи вызовом какого то метода?
...
Рейтинг: 0 / 0
phantom reference vs weak reference
    #39378157
questioner
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
questionerBlazkowicz,

Получается для weak и soft попадание в очередь это фактически очистка из кучи, а для phantom это событие, когда можно явно очистить из кучи вызовом какого то метода?



Если weak/soft ссылка оказалась в referenceQueue значит память объекта, на который она указывала уже освобождена коллектором?

а для фантомной ссылки, я , судя по поведению кода, ошибся. сначала вызывается finalize, потом попадаем в очередь и теперь мы имеем право высвободить память под объект, на который указывает ссылка. Если мы делаем reference.clear(), то память высвобождается. Если не делаем, то gc сам это сделает, когда эта ссылка будет не нужна.

это верно?
...
Рейтинг: 0 / 0
phantom reference vs weak reference
    #39378158
questioner
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Blazkowiczquestionerхотя в дебаггере в поле referent я вижу объект Bar:

Это вопрос или констатация факта?
http://stackoverflow.com/questions/7048767/why-are-phantom-references-not-cleared-as-they-are-enqueued

ааа, понял кажется.

в ReferenceQueue ведь тоже хранится фантомная ссылка, а её get() всегда null возвращает
...
Рейтинг: 0 / 0
phantom reference vs weak reference
    #39378170
questioner
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Blazkowicz,

Ещё одна мысль, подтверждение которой я хотел бы получить.

Для фантомных ссылок сама ссылка полученная как

Код: java
1.
PhantomReference<Bar> phantomReference = new PhantomReference<Bar>(new Bar(), objectReferenceQueue);



уже не имеет никакого смысла. get всё равно вернет null.

когда в очереди
авторobjectReferenceQueue
появилось значение, то значит gc готов почистить объект из памяти и что finalize он уже вызвал.
Наша задача вызвать
Код: java
1.
objectReferenceQueue.poll().clear() 

для освобождения памяти.

в случае weak/soft references попадание в очередь сигнализирует о том, что объект уже выгружен из памяти. На ссылке из очереди никакого метода не вызвать, чтобы получить какую-либо информацию об умершем объекте. Важен сам факт попадания в очередь.
...
Рейтинг: 0 / 0
phantom reference vs weak reference
    #39378173
questioner
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
ещё получается, что если мы явно вызвали clear то значит мы знаем, что память будет освобождена. сразу после этого вызывается finalize если он не был до этого вызван и чистится память. ни в какую очередь ничего не попадает
...
Рейтинг: 0 / 0
phantom reference vs weak reference
    #39378212
Фотография Blazkowicz
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
questionerуже не имеет никакого смысла. get всё равно вернет null.

Верно. Поэтому нужно разделять, те объекты, которые мы ожидаем быть собранными через GC и те объекты, которые мы закрываем.
Это не один и тот же объект, а два разных.
Например, можно сделать наследника PhantomReference и в нем хранить некую ссылку на ресурс. Это может быть путь к файлу, или адрес в памяти. Когда объект готов быть собраным, мы из наследника PhantomReference получаем эту ссылку и, например, удаляем файл или чистим чего-то нативное по сохраненному адресу.

В этом-то и смысл и разница с finilize. В finilize ты получаешь ссылку на объект и он может легко утечь обратно в живые объекты. А PhantomReference у тебя нет ссылки на объект. И он уже не утечен. Но ссылку на ресурс надо хранить отдельно.
...
Рейтинг: 0 / 0
phantom reference vs weak reference
    #39378214
Фотография Blazkowicz
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
questionerещё получается, что если мы явно вызвали clear то значит мы знаем, что память будет освобождена. сразу после этого вызывается finalize если он не был до этого вызван и чистится память. ни в какую очередь ничего не попадает
Забудь про finalize. Зачем ты его вплетаешь в вопросы про PhantomReference? Это совсем иной deprecated механизм.
...
Рейтинг: 0 / 0
phantom reference vs weak reference
    #39378223
questioner
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Blazkowiczquestionerещё получается, что если мы явно вызвали clear то значит мы знаем, что память будет освобождена. сразу после этого вызывается finalize если он не был до этого вызван и чистится память. ни в какую очередь ничего не попадает
Забудь про finalize. Зачем ты его вплетаешь в вопросы про PhantomReference? Это совсем иной deprecated механизм.

я просто программку запустил, проверил. впредь забываю)
...
Рейтинг: 0 / 0
phantom reference vs weak reference
    #39378264
questioner
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Blazkowicz,

c Phantom разобрался, с weak/soft без ReferenceQueue тоже.

осталось weak/soft с параметром ReferenceQueue
Зачем может понадобиться момент, когда память освобождена для weak/soft ссылок? чтобы попробовать занять эту память чем-то ещё?
...
Рейтинг: 0 / 0
phantom reference vs weak reference
    #39378269
questioner
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
и ещё теперь довольно спорно, что по слабости

strong->soft->weak->phantom.

Phantom вообще особняком стоит.
...
Рейтинг: 0 / 0
phantom reference vs weak reference
    #39378355
questioner
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
забыл никquestionerзачем вообще очередь? чтобы передавать её в несколько конструкторов?

http://samolisov.blogspot.com.by/2011/09/phantomreferences-java.html

Я наверное понял что вас смущает. Ваш вопрос сводится к тому - зачем нужна очередь, если теоретически можно добавить метод isCollected в тот же PhantomReference. Ответ состоит в том, что поток выполняющий ваш код и поток сборки мусора это два разных потока, которые могут увидеть одну и ту же переменную в разном состоянии(data race), а так как очистка объекта это не атомарное действие(надо вызвать как finalise так и физически очистить память от байтов и тд), то использовать PhantomReference опасно, так как finalise уже отработал а память физически не удалилась и тд. Поэтому вводится третий объект очередь, который правильно синхронизирован, и если метод poll вернул что-то - значит все действия по очистке ГАРАНТИРОВАННО завершились - и вы можете приступать к кастомной очистке, как-то так.


а какие операции опасны, если использовать ссылку не из очереди а саму ссылку?
Допустим:

Код: java
1.
 WeakReference<Bar> ref = new WeakReference<Bar>(new Bar(),weakReferenceQueue);




я не слежу за weakReferenceQueue, что мне можно и не можно делать с ref?
...
Рейтинг: 0 / 0
phantom reference vs weak reference
    #39378477
questioner
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Blazkowicz,

ещё хотел бы узнать про практическое применение softReference.
с weak вроде понятно. Это кеширование. пример WeakHashMap

а вот soft неочевидно. к тому никакого SoftHashMap не существует
...
Рейтинг: 0 / 0
phantom reference vs weak reference
    #39378483
Фотография Blazkowicz
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
questionerЭто кеширование. пример WeakHashMap
А вот это как раз распространенное заблуждение. Открой хотя бы JavaDoc

https://docs.oracle.com/javase/8/docs/api/java/lang/ref/SoftReference.html Soft references are most often used to implement memory-sensitive caches

https://docs.oracle.com/javase/8/docs/api/java/lang/ref/WeakReference.html Weak references are most often used to implement canonicalizing mappings .
...
Рейтинг: 0 / 0
phantom reference vs weak reference
    #39378733
questioner
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Blazkowicz
https://docs.oracle.com/javase/8/docs/api/java/lang/ref/WeakReference.html Weak references are most often used to implement canonicalizing mappings .

Код: java
1.
2.
3.
4.
5.
6.
7.
class Registry {
     private Set registeredObjects = new HashSet();

     public void register(Object object) {
         registeredObjects.add( new WeakReference(object) );
     }
 }



Приведен класс и написано, что сет сможет почиститься.

авторYou can use this technique for caching, cataloguing, etc

Чего-то я не проникся. зачем может понадобиться кеш, который даже никто не будет стараться сохранить. И что же всё таки за canonicalizing mappings.
...
Рейтинг: 0 / 0
phantom reference vs weak reference
    #39378742
Фотография Usman
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
questionerникто не будет стараться сохранитьКэш будет храниться до тех пор, пока не заполнится память: сработает "не форсированный" GC,
который сметет WeakReference-объекты одним из первых.
...
Рейтинг: 0 / 0
phantom reference vs weak reference
    #39378791
questioner
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Usmanquestionerникто не будет стараться сохранитьКэш будет храниться до тех пор, пока не заполнится память: сработает "не форсированный" GC,
который сметет WeakReference-объекты одним из первых.

По описанию больше похоже на softReference.
...
Рейтинг: 0 / 0
phantom reference vs weak reference
    #39378813
Фотография Usman
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
questionerUsmanпропущено...
Кэш будет храниться до тех пор, пока не заполнится память: сработает "не форсированный" GC,
который сметет WeakReference-объекты одним из первых.

По описанию больше похоже на softReference.Согласен, этот случай подходит и для SoftReference-объектов. Но если явно вызвать сборщик мусора,
когда память еще не заполнена до критического предела (еще замного до OutOfMemoryException), SoftReference-ссылки останутся.
...
Рейтинг: 0 / 0
phantom reference vs weak reference
    #39378835
questioner
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Usman,

Я тогда прошу прощения, мысль не уловил. Просто Ваша фраза начиналась с того, что gc вызовется когда память заполнится. В этот момент удалятся softReference. WeakReference могут быть удалены в любой момент. Зачем такой кеш, который может быть удален в любой момент?
...
Рейтинг: 0 / 0
phantom reference vs weak reference
    #39378873
Фотография Usman
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
questionerЗачем такой кеш, который может быть удален в любой момент?Не удален, а очищен. И, соответственно, после очередного GC наш WeakReference-кэш начнет сохранять все объекты по новой:Weak reference objects, which do not prevent their referents from being made finalizable, finalized, and then reclaimed . Weak references are most often used to implement canonicalizing mappings.Это подходит не для всех типов кэша. В данном случае подразумевается, что создание объектов кэша будет менее затратным .
Соответственно, для хранения более "тяжелых" объектов, лучше воспользоваться SoftReference-ссылками.
P.S. http://wiki.c2.com/?CanonicalizedMapping Sun caused the problem for us with stupid naming: the terms "soft", "weak" and "phantom" convey absolutely nothing relevant to anyone besides the person (smoking what?) who applied them to these classes.
...
Рейтинг: 0 / 0
phantom reference vs weak reference
    #39378876
questioner
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
UsmanquestionerЗачем такой кеш, который может быть удален в любой момент?Не удален, а очищен. И, соответственно, после очередного GC наш WeakReference-кэш начнет сохранять все объекты по новой:Weak reference objects, which do not prevent their referents from being made finalizable, finalized, and then reclaimed . Weak references are most often used to implement canonicalizing mappings.Это подходит не для всех типов кэша. В данном случае подразумевается, что создание объектов кэша будет менее затратным .
Соответственно, для хранения более "тяжелых" объектов, лучше воспользоваться SoftReference-ссылками.
P.S. http://wiki.c2.com/?CanonicalizedMapping Sun caused the problem for us with stupid naming: the terms "soft", "weak" and "phantom" convey absolutely nothing relevant to anyone besides the person (smoking what?) who applied them to these classes.


А для каких подходит?

Неужели WeakReference создавать проще, чем soft? разница ведь только в том, что weak будет чиститься чаще.

Пока что из адекватного, что я вычитал и осознал это только то, что допустим у нас есть класс с одним полем, хотим добавить еще поле, но добавлять его в класс нам нельзя.

Заводим WeakHahMap объект в качестве ключа, объект с новым полем в качестве значения.

При этом если мы теряем ссылку на ключ в программе, то вся энтря может быть удалена из мапы.
...
Рейтинг: 0 / 0
phantom reference vs weak reference
    #39378895
Фотография Usman
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
questionerразница ведь только в том, что weak будет чиститься чаще.Это просто еще один вариант реализации кэша.
Например, у нас есть ReflectionUtils - класс, который позволяет получить имена полей,
методов определенного класса через рефлексию. Класс содержит поле declaredMethodsCache
и метод getDeclaredMethods(clazz) . Посмотрев на реализацию метода мы увидим, что прежде
чем вернуть список методов сначала опрашивается кэш. Если в кэше нет, мы вычисляем заново.
Задумка - супер ! Если не считать того, что там "StrongReference-кэш" ! Логичней всего следовало
бы сделать его SoftReference'ным. Но еще лучше - WeakReference !!!
Почему?

Все зависит от частоты использования класса ReflectionUtils.

Как часто мы будем пользоваться этим утилитным классом? Согласен, рефлексия работает не быстро.
Но все же мы можем запросить список методов по новой (согласно логике работы метода getDeclaredMethods).
Объявив поле declaredMethodsCache через WeakReference мы не будем захламлять, и самое главное, будем
периодически высвобождать память для более важных задач ( не дожидаясь OutOfMemoryError !!! ).
Лично я не вижу смысла кэшировать список Declared-методов и держать их в кэше до конца жизни программы.

Код: plaintext
END-OF-IMHO
...
Рейтинг: 0 / 0
phantom reference vs weak reference
    #39378897
questioner
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Usmanquestionerразница ведь только в том, что weak будет чиститься чаще.Это просто еще один вариант реализации кэша.
Например, у нас есть ReflectionUtils - класс, который позволяет получить имена полей,
методов определенного класса через рефлексию. Класс содержит поле declaredMethodsCache
и метод getDeclaredMethods(clazz) . Посмотрев на реализацию метода мы увидим, что прежде
чем вернуть список методов сначала опрашивается кэш. Если в кэше нет, мы вычисляем заново.
Задумка - супер ! Если не считать того, что там "StrongReference-кэш" ! Логичней всего следовало
бы сделать его SoftReference'ным. Но еще лучше - WeakReference !!!
Почему?

Все зависит от частоты использования класса ReflectionUtils.

Как часто мы будем пользоваться этим утилитным классом? Согласен, рефлексия работает не быстро.
Но все же мы можем запросить список методов по новой (согласно логике работы метода getDeclaredMethods).
Объявив поле declaredMethodsCache через WeakReference мы не будем захламлять, и самое главное, будем
периодически высвобождать память для более важных задач ( не дожидаясь OutOfMemoryError !!! ).
Лично я не вижу смысла кэшировать список Declared-методов и держать их в кэше до конца жизни программы.

Код: plaintext
END-OF-IMHO



видеть или не видеть смысла это одно, а реально ли приложение будет дольше работать от этого?
Если нет outOfMemory, то пусть лежит. (или всё таки различие есть?)

а в случае SoftReference мы явно получим выигрыш в том, что вычислять нам придётся реже.
...
Рейтинг: 0 / 0
phantom reference vs weak reference
    #39378997
uid unique
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
questionerBlazkowicz,

ещё хотел бы узнать про практическое применение softReference.
с weak вроде понятно. Это кеширование. пример WeakHashMap

а вот soft неочевидно. к тому никакого SoftHashMap не существует

Soft частенько применяется в пулах, он работает по принципу пускай полежит объект пока памяти хватает даже если никто его кроме softreference не использует. Не будет памяти хватать тогда объект у которого только softref снесет сборщик мусора. Первый раз наткнулся на softReference ковыряясь в исходниках библиотеки которая реализовала пул массивов int/long 2х кратной длины (массивы длиной 64, 128, 256 и тд), чтобы не создавать массивы постоянно, использовался пул (версия Java была 1.3 если не ошибаюсь)
...
Рейтинг: 0 / 0
phantom reference vs weak reference
    #39379107
Vurn
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Поясню. Weak(Soft)Reference - это ссылка на объект, который может быть убран сборщиком мусора, и который объект может быть придется тебе пересоздать. Сама по себе weak-ссылка держит уже сильную ссылку на объект. Скажем удобно хранить большое
изображение. Если оно в памяти есть, ты получишь сильную ссылку и выведешь его на экран. Если памяти не хватает, его gc уберет, а потом ты перечитаешь с диска еще раз.

Phantom - несколько другое. Ты создаешь сам объект PhantomReference, информируешь GC, куда, в какую очередь ReferenceQueue положить этот самый объект PhantomReference, когда он, GC, удалит подвязанный на этот объект другой объект по сильной ссылке. Важно! Phantom - это не контейнер для ссылки на другой объект! Это - watch-dog, который начнет гавкать, когда "сильный-объект" будет окончательно удален из памяти.

Зачем используется Phantom? Простой пример. Пусть у тебя в оперативке большой объект, типа изображения или DOM-модель. Этот объект занимает много памяти. Тебе надо, но ты не хочешь грузить другие объекты, пока этот большой объект не уйдет из памяти, дабы не получить случайно OutOfMemoryError. Тогда ты создаешь Phantom на этот большой объект и после этого тред садиться на контроль очереди RefQueue. Как только сам большой объект будет окончательно удален, в очереди появится наш этот PhantomReference и с этого момента ты можешь начать грузить/создавать другой большой объект.
...
Рейтинг: 0 / 0
phantom reference vs weak reference
    #39379123
questioner
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
VurnPhantom - несколько другое. Ты создаешь сам объект PhantomReference, информируешь GC, куда, в какую очередь ReferenceQueue положить этот самый объект PhantomReference, когда он, GC, удалит подвязанный на этот объект другой объект по сильной ссылке. Важно! Phantom - это не контейнер для ссылки на другой объект! Это - watch-dog, который начнет гавкать, когда "сильный-объект" будет окончательно удален из памяти.
.

Нет, неверно. Это справедливо для soft/weak, но не для фантомных ссылок.

Фантомные ссылки попадают в очередь ДО! очистки памяти
...
Рейтинг: 0 / 0
phantom reference vs weak reference
    #39379237
vimba
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Мельком просмотрел топик, кажись в нём тема сисек преимущество использования PhantomReference супротив finalize так и не раскрыта.

И то и другое используется с целью предотвращения утечек ценных ресурсов, которая может произойти в случае если пользователь неправильно использует API, например явно не закрывает сокет, или утечка происходит в результате непредвиденной ошибки, когда сценарий использования ресурса так просто try/finaly не засунешь. Спрашивается нафига для этих целей нужны танцы вокруг PhantomReference, если finalize пишется в одну строчку с делегаций работы уже готовому методу закрытия ресурса?

Все дело в том, что при использовании finalize пользователь получает обухом по голове платит отложенной окончательной сборкой объекта и запуском финализеров всегда, не зависимо от того правильно ли он использует API или нет, хоть тыщу раз следуй лучшим практикам, закрывай все ресурсы, но если у ресурсов переопределен finalize, то ты как пользователь за это заплатишь, и что самое неприятное заплатишь в Stop the World паузе когда GC будет запихивать объекты в очередь для финализации, таким образом затягивая STW.

В то же самое время грамотная реализация предотвращение утечек, сделанная прямыми руками на основе PhantomReference, хоть и требует натаптывания гораздо большего количества кода, обеспечивает то свойство, что хороший пользователь API, который закрывает ресурсы явно, ничего(практически ничего) не платит за наличие такой опции как автоматическое предотвращение утечек. Достигается это тем, что в методе который пользователь явно вызывает для закрытия ресурса зануляется единственная сильная ссылка на PhantomReference, и поскольку сама PhantomReference становится unreachable, то ни в какую ReferenceQueue GC её не добавит. Соответсвенно, используй наш API грамотно и получи бонус в облегчении GC.

Вот хорошая статья по теме Ragozin. Finalizers and References in Java содержит в том числе и бенчмарки которые показывают, что с PhantomReference можно действительно сократить нагрузку на GC по сравнению с finalize, бенчмарки в том числе можно погонять скачав с github .

Ну и может быть стоит посмотреть Никита Сальников-Тарновский — Убери за собой!

YouTube Video
...
Рейтинг: 0 / 0
phantom reference vs weak reference
    #39397689
questioner
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
https://docs.oracle.com/javase/7/docs/api/java/lang/ref/PhantomReference.html Phantom reference objects, which are enqueued after the collector determines that their referents may otherwise be reclaimed. Phantom references are most often used for scheduling pre-mortem cleanup actions in a more flexible way than is possible with the Java finalization mechanism.
If the garbage collector determines at a certain point in time that the referent of a phantom reference is phantom reachable, then at that time or at some later time it will enqueue the reference.

In order to ensure that a reclaimable object remains so, the referent of a phantom reference may not be retrieved: The get method of a phantom reference always returns null.

Unlike soft and weak references, phantom references are not automatically cleared by the garbage collector as they are enqueued. An object that is reachable via phantom references will remain so until all such references are cleared or themselves become unreachable.

Выделенную фразу я понимал так, что для weak/soft ссылок попадание в очередь является критерием того, что память из под этих объектов, на которые указывали ссылки уже почищена, а для PhantomReference это время для нас освободить ресурсы и после этого либо сами сносим объект, либо теряем phantom ссылку.

но написав кусок кода, всё стало непонятно совсем.

Код: java
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
22.
23.
24.
25.
26.
27.
public class SimpleGCExample {
    public static void main(String[] args) throws InterruptedException {
        ReferenceQueue<Object> queue = new ReferenceQueue<>();
        SimpleGCExample e = new SimpleGCExample();
        Reference<Object> pRef = new PhantomReference<>(e, queue),
                wRef = new WeakReference<>(e, queue);
        e = null;
        for (int count = 0, collected = 0; collected < 2; ) {
            Reference ref = queue.remove(100);
            if (ref == null) {
                System.gc();
                count++;
            } else {
                collected++;
                System.out.println((ref == wRef ? "weak" : "phantom")
                        + " reference enqueued after " + count + " gc polls");
            }
        }
    }

    @Override
    protected void finalize() throws Throwable {
        System.out.println("finalizing the object in " + Thread.currentThread());
        Thread.sleep(100);
        System.out.println("done finalizing.");
    }
}




авторweak reference enqueued after 1 gc polls
finalizing the object in Thread[Finalizer,8,system]
done finalizing.
phantom reference enqueued after 2 gc polls

Насколько я понимаю, вызов finalize это точно последний вызов непосредственно перед высвобождением памяти.
Получается всё наоборот. фантомная ссылка на объект попадает в очередь только после высвобождения памяти а weak ссылка попадает в очередь до высвобождения памяти ибо до вызова finalize
...
Рейтинг: 0 / 0
phantom reference vs weak reference
    #39397735
Alexey Tomin
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
questionerПолучается всё наоборот. фантомная ссылка на объект попадает в очередь только после высвобождения памяти а weak ссылка попадает в очередь до высвобождения памяти ибо до вызова finalize

Читайте .

По сути- фантомные ссылки нужны только для очереди (замена finalize), и только они для очереди и нужны (класть туда другие ссылки бессмысленно).
При этом нормально, что для одного объекта будет создана пара ссылок soft+phantom или weak+phantom. Первая- чтобы был доступ, вторая- для уборки.

PS: я вообще не вижу особого смысла в phantom ссылке, если не используется soft или weak.
...
Рейтинг: 0 / 0
phantom reference vs weak reference
    #39397741
Alexey Tomin
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Alexey TominquestionerПолучается всё наоборот. фантомная ссылка на объект попадает в очередь только после высвобождения памяти а weak ссылка попадает в очередь до высвобождения памяти ибо до вызова finalize

Читайте .

По сути- фантомные ссылки нужны только для очереди (замена finalize), и только они для очереди и нужны (класть туда другие ссылки бессмысленно).
При этом нормально, что для одного объекта будет создана пара ссылок soft+phantom или weak+phantom. Первая- чтобы был доступ, вторая- для уборки.

PS: я вообще не вижу особого смысла в phantom ссылке, если не используется soft или weak.

Хотя нормально работает и прямая вставка в очередь и Soft/Weak ссылок.
...
Рейтинг: 0 / 0
phantom reference vs weak reference
    #39397818
questioner
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Alexey Tomin,

Я ж не про использование спрашивал а про конкретное поведение.

finalize в примере используется только для того, чтобы показать реальное время когда объект подыхает.

https://docs.oracle.com/javase/7/docs/api/java/lang/ref/PhantomReference.html Unlike soft and weak references, phantom references are not automatically cleared by the garbage collector as they are enqueued.

Что это тогда значит? поведение написанного мною примера противоречит доке?
...
Рейтинг: 0 / 0
48 сообщений из 48, показаны все 2 страниц
Форумы / Java [игнор отключен] [закрыт для гостей] / phantom reference vs weak reference
Найденые пользователи ...
Разблокировать пользователей ...
Читали форум (0):
Пользователи онлайн (0):
x
x
Закрыть


Просмотр
0 / 0
Close
Debug Console [Select Text]