Виды ссылок в Java

Мы немало уже говорили про Garbage Collector и про то, как именно он работает.

Теперь давайте рассмотрим какие бывают ссылки в языке Java и чем они отличаются друг от друга и как их обрабатывает Сборщик Мусора.

Для ссылок есть абстрактный класс Reference<T>, от которого наследуются остальные типы ссылок (не все).

Итак, есть 4 типа ссылок

  1. Сильная ссылка (Strong Reference)
  2. Слабая ссылка (Weak Reference)
  3. Мягкая ссылка (Soft Reference)
  4. Фантомная ссылка (Phantom Reference)

Все программисты знакомы с первым видом ссылок, так как используют ее каждый день. Но огромная часть программистов и не слышала про остальные типы. Давайте разберем подробнее.

  1. Сильная ссылка. Она создается каждый раз, когда аллоцируем место в памяти через оператор new.

Итак, в данном примере создается некий объект, сохраняется по сильной ссылке в переменную. После чего переменная уже указывает на null. Значит уже на второй строке объект SimpleObject(123) доступен для сборщика мусора, так как на него нет ни одной явной ссылки. Здесь нужно понимать, что simpleObject и есть ссылка, которая при создании указывала на объект с айди 123. После обнуления сама ссылка уже хранит null и доступна для сборщика мусора.

2. Слабая ссылка.

Несколько фактов.

  • Этот тип ссылок используется как ключ в WeakHashMap чтобы обращаться к объектам.
  • Если JVM обнаружила объект только со слабой ссылкой (т.е. нет ни сильной ни мягкой ссылки) то объект будет помечен для сборщика мусора. (см. статью)
  • Для создания слабой ссылки используется класс java.lang.ref.WeakReference

Давайте напишем маленький пример использования.

Сначала создаем объект по сильной ссылке, вызываем у него метод вывода данных в консоль. После чего создаем слабую ссылку от нашей сильной ссылки. После чего обнуляем сильную ссылку. Теперь SimpleObject(123) доступен для сборщика мусора (но будет собран только если JVM понадобится память). Но, так как мы обернули в слабую ссылку, то можем теперь присвоить первой ссылке объект через метод get() у слабой ссылки. После чего проверяем, что она не пуста (на экране предупреждение о NullPointerException).

Итак, в чем суть? Что мы создали слабую связь с объектом и можем обращаться к нему даже после того, как сильная ссылка обнулилась. Грубо говоря, пока у нас есть слабая ссылка, мы можем вернуть наш объект.

Область применения слабой ссылки. Можно использовать для кратковременного сохранения данных (кэш).

3. Мягкая ссылка.

Посмотрим исходники и прочитаем документацию.

Мягкие ссылки используются для создания кэшей. Так как они подчищаются тогда, когда JVM остро нуждается в памяти. Все мягкие ссылки гарантированы будут подчищены перед тем как бросить OutOfMemoryError (см. пример).

В самом классе наблюдаем 2 переменных: clock & timestamp и как говорит документация, первую обновляет сборщик мусора, а вторая нужна для обновления при каждом вызове метода get( ). JVM может использовать второе поле при пометке объекта для сбора, но это не точно 🙂

Давайте рассмотрим тот же пример что и со слабой ссылкой, но с мягкой.

Пройдемся дебагером и заметим, что в referent мягкой ссылки мы имеем тот же самый объект, что и в сильной ссылке.

4. Фантомная ссылка.

В чем отличие фантомной ссылки от остальных слабых ссылок — в том, что она хоть и также доступна для сборщика мусора, но в отличие от остальных типов ссылок JVM кладет фантомные ссылки в очередь ссылок (reference queue). Они кладутся в очередь после того, как метод finalize( ) был вызван.

Самое интересное, что получить объект нельзя как в случае с мягкой ссылкой или слабой, так как здесь метод get( ) возвращает null. Тогда каково предназначение фантомной ссылки? Хранить объект, но не давать сборщику мусора уничтожить его?

Более подробно о фантомной ссылке можете прочитать здесь. Позже распишем свои примеры.

 

 

Запись опубликована в рубрике Программирование Java. Добавьте в закладки постоянную ссылку.

Добавить комментарий

Ваш e-mail не будет опубликован. Обязательные поля помечены *