Статьи

Разница между WeakReference и SoftReference, PhantomReference и Strong reference в Java

WeakReference и SoftReference были добавлены в Java API с давних времен, но не каждый Java-программист знаком с ним. Это означает, что существует разрыв между тем, где и как использовать WeakReference и SoftReference в Java . Ссылочные классы особенно важны в контексте работы сборщика мусора . Как мы все знаем, что сборщик мусора восстанавливает память от объектов, которые могут быть использованы для сборки мусора, но не многие программисты знают, что это право определяется на основании того, какие ссылки указывают на этот объект. Это также главное отличие WeakReference от SoftReference в Java . Сборщик мусора может собирать объект, если на него указывают только слабые ссылки, и они охотно собираются, с другой стороны, объекты с SoftReference собираются, когда JVM абсолютно нуждается в памяти. Такое специальное поведение SoftReference и WeakReference делает их полезными в определенных случаях, например, SoftReference выглядит идеально для реализации кэшей, поэтому, когда JVM требуется память, она удаляет объект, на который указывает только SoftReference. С другой стороны, WeakReference отлично подходит для хранения метаданных, например, для хранения ссылки ClassLoader. Если класс не загружен, то нет смысла хранить ссылку на ClassLoader, а WeakReference делает ClassLoader подходящим для сборки мусора, как только удаляется последняя сильная ссылка. В этой статье мы рассмотрим еще несколько различных ссылок в Java, например, Strong reference и Phantom reference.

Слабая ссылка против SoftReference в Java

Для тех, кто не знает, в Java есть четыре вида ссылок:

  1. Сильная ссылка
  2. Слабая ссылка
  3. Soft Reference
  4. Призрак Ссылка

Strong Reference является наиболее простым, поскольку мы используем его в повседневной жизни, например, в коде String s = «abc», ссылочная переменная s имеет сильную ссылку на объект String «abc». Любой объект, к которому прикреплена ссылка Strong, не подходит для сборки мусора . Очевидно, что это объекты, которые нужны Java-программе. Слабая ссылка представлена ​​с использованием класса java.lang.ref.WeakReference, и вы можете создать слабую ссылку, используя следующий код:

1
2
3
Counter counter = new Counter(); // strong reference - line 1
WeakReference<Counter> weakCounter = new WeakReference<Counter>(counter); //weak reference
counter = null; // now Counter object is eligible for garbage collection

Теперь, как только вы установите сильную ссылку counter = null, объект счетчика, созданный в строке 1, становится пригодным для сборки мусора; потому что он больше не имеет строгой ссылки и слабой ссылки по ссылочной переменной weakCounter не может помешать сборке объекта Counter. С другой стороны, если бы это был Soft Reference, объект Counter не будет собирать мусор до тех пор, пока JVM абсолютно не понадобится память. Мягкая ссылка в Java представлена ​​с использованием класса java.lang.ref.SoftReference. Вы можете использовать следующий код для создания SoftReference в Java

1
2
3
4
Counter prime = new Counter();  // prime holds a strong reference - line 2
SoftReference<Counter> soft = new SoftReference<Counter>(prime) ; //soft reference variable has SoftReference to Counter Object created at line 2
 
prime = null// now Counter object is eligible for garbage collection but only be collected when JVM absolutely needs memory

После создания сильной ссылки равной нулю, объект Counter, созданный в строке 2, имеет только одну мягкую ссылку, которая не может помешать его сборке мусора, но может задержать сбор, что очень важно в случае WeakReference. Из-за этого основного различия между SoftReference и WeakReference , SoftReference больше подходят для кэширования, а WeakReference больше подходят для хранения метаданных . Одним из удобных примеров WeakReference является WeakHashMap, который представляет собой другую реализацию интерфейса Map, такую ​​как HashMap или TreeMap, но с одной уникальной функцией. WeakHashMap оборачивает ключи как WeakReference, что означает, что когда сильная ссылка на фактический удаленный объект, WeakReference, присутствующая внутри WeakHashMap, не препятствует их сборке мусора.

Фантомная ссылка — это третий тип ссылочного типа, доступный в пакете java.lang.ref. Фантомная ссылка представлена ​​классом java.lang.ref.PhantomReference. Объект, на который указывает только ссылка на Фантом, может быть собран в любое время, когда это нравится Сборщику мусора. Подобно WeakReference и SoftReference, вы можете создать PhantomReference с помощью следующего кода:

1
2
3
4
DigitalCounter digit = new DigitalCounter(); // digit reference variable has strong reference - line 3
PhantomReference<DigitalCounter> phantom = new PhantomReference<DigitalCounter>(digit); // phantom reference to object created at line 3
 
digit = null;

Как только вы удалите ссылку Strong, объект DigitalCounter, созданный в строке 3, можно в любой момент собрать мусором, поскольку на него указывает только еще одна ссылка PhantomReference, которая не может предотвратить его от GC’d.

Помимо знаний о WeakReference, SoftReference, PhantomReference и WeakHashMap, существует еще один класс с именем ReferenceQueue, который стоит знать. Вы можете предоставить экземпляр ReferenceQueue при создании любого WeakReference, SoftReference или PhantomReference, как показано в следующем коде:

1
2
3
4
ReferenceQueue refQueue = new ReferenceQueue(); //reference will be stored in this queue for cleanup
 
DigitalCounter digit = new DigitalCounter();
PhantomReference<DigitalCounter> phantom = new PhantomReference<DigitalCounter>(digit, refQueue);

Ссылка на экземпляр будет добавлена ​​в ReferenceQueue, и вы можете использовать его для выполнения любой очистки, опрашивая ReferenceQueue. Жизненный цикл объекта хорошо суммируется с помощью этой диаграммы.

Слабая Сильная Мягкая и Фантомная Ссылка в Java

Вот и все о разнице между WeakReference и SoftReference в Java . Мы также изучили основы ссылочных классов, например, слабые, мягкие и фантомные ссылки в Java, а также WeakHashMap и ReferenceQueue. Тщательное использование справочных материалов может помочь в сборке мусора и улучшить управление памятью в Java.