HTML Diff
0 added 0 removed
Original 2026-01-01
Modified 2026-03-10
1 <p>Теги: null, java, get, delete, gc, finalize(), типы ссылок в java, узнать о том, что объект удалён, phantom reference, java.lang.ref.phantomreference, referencequeue, finalize</p>
1 <p>Теги: null, java, get, delete, gc, finalize(), типы ссылок в java, узнать о том, что объект удалён, phantom reference, java.lang.ref.phantomreference, referencequeue, finalize</p>
2 <p>В некоторых языках сделать это очень просто: вызвал<strong>delete</strong>, и можешь быть уверен - памяти стало больше. В Java всё немного сложнее.</p>
2 <p>В некоторых языках сделать это очень просто: вызвал<strong>delete</strong>, и можешь быть уверен - памяти стало больше. В Java всё немного сложнее.</p>
3 <p>С одной стороны, отлично, что нам не нужно писать<strong>delete</strong>"ручками".<strong>GC</strong>всё сделает за тебя. Потерял ссылку на объект и ничего страшного! Память будет освобождена и без ссылки. Утечки не будет. С другой стороны, очень хочется иногда написать<strong>delete</strong>, но нет такой возможности.</p>
3 <p>С одной стороны, отлично, что нам не нужно писать<strong>delete</strong>"ручками".<strong>GC</strong>всё сделает за тебя. Потерял ссылку на объект и ничего страшного! Память будет освобождена и без ссылки. Утечки не будет. С другой стороны, очень хочется иногда написать<strong>delete</strong>, но нет такой возможности.</p>
4 <h2>И, в самом деле, как узнать, что объект удалён?</h2>
4 <h2>И, в самом деле, как узнать, что объект удалён?</h2>
5 <p>Можно подписаться на события<strong>GC</strong>. Но они не про конкретный объект, а про событие для всех объектов. Можно переопределить<strong>finalize()</strong>(у всех классов он есть) и обработать событие в нём.</p>
5 <p>Можно подписаться на события<strong>GC</strong>. Но они не про конкретный объект, а про событие для всех объектов. Можно переопределить<strong>finalize()</strong>(у всех классов он есть) и обработать событие в нём.</p>
6 <p>Но если таких объектов будет много, это может сильно снизить скорость работы<strong>GC</strong>. А медленный<strong>GC</strong>- это большие паузы в работе всего приложения. К счастью в Java есть отличный способ узнать о том, что объект удалён.</p>
6 <p>Но если таких объектов будет много, это может сильно снизить скорость работы<strong>GC</strong>. А медленный<strong>GC</strong>- это большие паузы в работе всего приложения. К счастью в Java есть отличный способ узнать о том, что объект удалён.</p>
7 <h2>Phantom reference</h2>
7 <h2>Phantom reference</h2>
8 <p>Фантомная ссылка - объект класса<strong>java.lang.ref.PhantomReference</strong>. Объект, на который существуют только фантомные ссылки, доступен сборщику мусора. Фантомная ссылка не даёт пользователю возможности "спасти" объект, создав на него сильную ссылку: метод<strong>get</strong>на ней всегда возвращает<strong>null</strong>.</p>
8 <p>Фантомная ссылка - объект класса<strong>java.lang.ref.PhantomReference</strong>. Объект, на который существуют только фантомные ссылки, доступен сборщику мусора. Фантомная ссылка не даёт пользователю возможности "спасти" объект, создав на него сильную ссылку: метод<strong>get</strong>на ней всегда возвращает<strong>null</strong>.</p>
9 <p>Зато с помощью фантомной ссылки можно определить, что объект собирается быть удалён. В силу этих особенностей фантомная ссылка бесполезна без объекта<strong>ReferenceQueue</strong>, поэтому для неё определён единственный конструктор:</p>
9 <p>Зато с помощью фантомной ссылки можно определить, что объект собирается быть удалён. В силу этих особенностей фантомная ссылка бесполезна без объекта<strong>ReferenceQueue</strong>, поэтому для неё определён единственный конструктор:</p>
10 ReferenceQueue&lt;Wiki&gt; queue = new ReferenceQueue&lt;Wiki&gt;(); //создание очереди PhantomReference&lt;Wiki&gt; ref = new PhantomReference&lt;Wiki&gt;(new Wiki("cyclowiki.org"), queue);<p>Основное предназначение фантомных ссылок - замена методу<strong>finalize</strong>, имеющему большое количество недостатков. С их помощью можно реализовать логику подготовки объекта к удалению, например освобождение захваченных им ресурсов, очистка сессии, сохранение состояния или логгирование.</p>
10 ReferenceQueue&lt;Wiki&gt; queue = new ReferenceQueue&lt;Wiki&gt;(); //создание очереди PhantomReference&lt;Wiki&gt; ref = new PhantomReference&lt;Wiki&gt;(new Wiki("cyclowiki.org"), queue);<p>Основное предназначение фантомных ссылок - замена методу<strong>finalize</strong>, имеющему большое количество недостатков. С их помощью можно реализовать логику подготовки объекта к удалению, например освобождение захваченных им ресурсов, очистка сессии, сохранение состояния или логгирование.</p>
11 <p>Фантомная ссылка, указывающая на удаляемый объект, попадает в<strong>ReferenceQueue</strong>, откуда она может быть извлечена. Поскольку базовая фантомная ссылка не предоставляет пользователю возможности определить, на какой именно объект она ссылается, стоит реализовывать собственного потомка класса<strong>PhantomReference</strong>, хранящего идентификатор объекта (не ссылку на сам объект, ибо это будет сильная ссылка - объект перестанет быть доступен сборщику мусора).</p>
11 <p>Фантомная ссылка, указывающая на удаляемый объект, попадает в<strong>ReferenceQueue</strong>, откуда она может быть извлечена. Поскольку базовая фантомная ссылка не предоставляет пользователю возможности определить, на какой именно объект она ссылается, стоит реализовывать собственного потомка класса<strong>PhantomReference</strong>, хранящего идентификатор объекта (не ссылку на сам объект, ибо это будет сильная ссылка - объект перестанет быть доступен сборщику мусора).</p>
12 <p>В таком случае после обращения к идентификатору можно однозначно определить, какой объект был удалён, и выполнить все необходимые операции.</p>
12 <p>В таком случае после обращения к идентификатору можно однозначно определить, какой объект был удалён, и выполнить все необходимые операции.</p>
13 <h2>Проще говоря</h2>
13 <h2>Проще говоря</h2>
14 <p><strong>Phantom reference</strong>- тоже ссылка на объект, как и нормальная ссылка. Но у нее всё по-своему. Получить объект по ней нельзя. Но можно найти её в специальном пуле ссылок для удалённых объектов. Создали ссылку, подождали<strong>GC</strong>, проверили в пуле. Если она там есть, значит объект был удалён.</p>
14 <p><strong>Phantom reference</strong>- тоже ссылка на объект, как и нормальная ссылка. Но у нее всё по-своему. Получить объект по ней нельзя. Но можно найти её в специальном пуле ссылок для удалённых объектов. Создали ссылку, подождали<strong>GC</strong>, проверили в пуле. Если она там есть, значит объект был удалён.</p>
15 <p><strong>А какие еще типы ссылок есть в Java? И зачем они нужны?</strong></p>
15 <p><strong>А какие еще типы ссылок есть в Java? И зачем они нужны?</strong></p>
16 <p><em>Знаете? Напишите в комментариях!</em></p>
16 <p><em>Знаете? Напишите в комментариях!</em></p>
17  
17