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<Wiki> queue = new ReferenceQueue<Wiki>(); //создание очереди PhantomReference<Wiki> ref = new PhantomReference<Wiki>(new Wiki("cyclowiki.org"), queue);<p>Основное предназначение фантомных ссылок - замена методу<strong>finalize</strong>, имеющему большое количество недостатков. С их помощью можно реализовать логику подготовки объекта к удалению, например освобождение захваченных им ресурсов, очистка сессии, сохранение состояния или логгирование.</p>
10
ReferenceQueue<Wiki> queue = new ReferenceQueue<Wiki>(); //создание очереди PhantomReference<Wiki> ref = new PhantomReference<Wiki>(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