Статьи

Понимание слабых ссылок Java

Я не мог обратить внимание на блог в последнее время, и в первую очередь я должен извиниться за то, что не поддерживал связь со всеми вами в мире технологий. Недавно я наткнулся на пакет java.lang.ref, который был доступен с Java 1.2, но по иронии судьбы я узнал об этом всего несколько дней назад. Просматривая несколько статей, рассказывающих о различных ссылочных типах, а также о java-документе, я был очень заинтригован и очень хотел испачкать руки каким-нибудь ссылочным кодом.

Я не буду говорить о каждом справочном классе, доступном в пакете java.lang.ref, поскольку это уже очень хорошо объяснено здесь . Давайте посмотрим на следующий фрагмент кода, который я написал, чтобы понять основные операции WeakReference .

01
02
03
04
05
06
07
08
09
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
import java.lang.ref.WeakReference; 
import java.util.HashMap; 
import java.util.Map; 
   
public class ReferencesTest { 
   
 private WeakReference<Map<Integer, String>> myMap; 
   
 public static void main(String[] args) { 
  new ReferencesTest().doFunction(); 
 
   
 private void doFunction() { 
   
  Map<Integer, String> map = new HashMap<Integer, String>(); 
  myMap = new WeakReference<Map<Integer, String>>(map); 
   
  map = null
  int i = 0
  while (true) { 
   if (myMap != null && myMap.get() != null) { 
    myMap.get().put(i++, "test" + i); 
   
    System.out.println("im still working!!!!"); 
   } else
   
    System.out 
      .println("*******im free*******"); 
   
   
   
  
 

Сначала я определил переменную экземпляра со слабой ссылкой, которой я назначаю экземпляр HashMap, инициализированный в методе doFunction (). Затем данные вводятся на карту через экземпляр слабой ссылки, а не напрямую через конкретный экземпляр созданной нами хэш-карты. Мы проверяем, чтобы карта была нулевой из-за того, как работает WeakReferences.

Во время выполнения программы слабая ссылка будет первой, которая будет собирать мусор, если к ней не привязаны мягкие или сильные ссылки. Поэтому, если памяти значительно недостаточно, или когда и если сборщик мусора сочтет нужным, слабая ссылка — сборщик мусора, и именно поэтому я включил в свой код инструкцию else, чтобы показать возникновение этой ситуации. Запустите это, установив минимальные значения –Xms и –Xmx, чтобы понять, как это работает, так как в противном случае вам придется ждать более длительный период, чтобы получить исключение нехватки памяти. А затем измените реализацию WeakReference на реализацию SoftReference и увидите, что программа действительно аварийно завершает работу после нескольких итераций. Это связано с тем, что SoftReferences гарантирует только очистку памяти непосредственно перед возникновением ошибки OutOfMemory. Но с WeakReference программа продолжает функционировать без остановки, потому что она почти всегда подходит для сборки мусора, и мы можем повторно инициализировать кеш и продолжать заполнять наш кеш.

Хорошая вещь о слабых ссылках заключается в том, что, по моему мнению, это один из лучших способов реализовать кэш в памяти, который мы обычно реализуем сами, когда нам нужно хранить данные, которые не постоянно изменяются, но часто используются в памяти, и когда стоимость переход к полноценной реализации кэширования, такой как кэш JBoss или EHCache, — это слишком много. Довольно часто я реализовывал решения для кэширования и также видел рабочий код, похожий на следующий фрагмент кода;

01
02
03
04
05
06
07
08
09
10
11
12
13
14
15
16
17
18
19
20
import java.util.HashMap; 
import java.util.Map; 
   
public class CacheTest { 
   
 private Map<String, Object> myAwesomeCache = new HashMap<String, Object>(100); 
    
 public Object getData(String id){ 
     
  Object objToReturn = null
     
  if(myAwesomeCache.containsKey(id)){ 
   objToReturn = myAwesomeCache.get(id); 
  }else
   // retrieve from the database and populate the in memory cache map 
  
     
  return objToReturn; 
 

Это всего лишь реализация базового уровня, чтобы выразить идею, что мы иногда используем Карты для построения реализаций кэширования в памяти. Мы должны отметить тот факт, что, хотя в этой реализации нет ничего по сути неправильного, в случае, когда у вашего приложения недостаточно памяти, было бы идеально, если бы сборщик мусора мог удалить это из памяти, чтобы освободить часть для другие процессы, которые нуждаются в этом. Но поскольку эта карта является надежной ссылкой, сборщик мусора не сможет пометить эту ссылку как пригодную для сбора. Лучшим решением было бы изменить реализацию кэширования с HashMap на WeakHashMap .

Javadoc определяет следующее о WeakHashMap;

«Реализация Map на основе хеш-таблицы со слабыми ключами. Запись в WeakHashMap будет автоматически удалена, если ее ключ больше не используется. Точнее говоря, наличие сопоставления для данного ключа не помешает тому, чтобы ключ был отброшен сборщиком мусора, то есть сделан финализируемым, завершенным, а затем восстановленным. Когда ключ отбрасывается, его запись эффективно удаляется с карты, поэтому этот класс ведет себя несколько иначе, чем другие реализации Map ».

Итак, в ретроспективе, я считаю, что когда вам нужна реализация кэширования в памяти, и для вас очень важно использовать память, использование WeakHashMap было бы полезно.

На этом я заканчиваю свои выводы по справочному пакету, и я приглашаю всех вас поделиться своим опытом в этом отношении, который высоко ценится.

ура

Ссылка: Понимание слабых ссылок Java от нашего партнера по JCG Динуки Арульератне в блоге « Мой путь через ИТ»