Когда использовать слабые и фантомные ссылки в Java
Я читаю много статей, но не понимаю - где мне на практике использовать слабые и фантомные ссылки? Мягкие ссылки - это хороший выбор для кеша, как я понимаю. Но слабый и призрачный, я не знаю, когда использовать. Пожалуйста, приведите примеры реальных задач, где мы должны их использовать.
5 ответов
Вы можете использовать слабые ссылки для кеша, просто как мягкие ссылки, как вы сказали.
Что хорошего в PhantomReferences? Мне известны только два серьезных случая: во-первых, они позволяют точно определить, когда объект был удален из памяти. На самом деле это единственный способ определить это. Как правило, это не так полезно, но может пригодиться в определенных очень специфических обстоятельствах, таких как манипулирование большими изображениями: если вы точно знаете, что изображение должно собираться мусором, вы можете подождать, пока оно действительно будет, прежде чем пытаться загрузить следующее изображение и, следовательно, сделать страшный OutOfMemoryError менее вероятным.
Во-вторых, PhantomReferences позволяет избежать фундаментальной проблемы с финализацией: методы finalize() могут "воскрешать" объекты, создавая новые сильные ссылки на них. Так что вы говорите? Проблема в том, что объект, который переопределяет finalize(), теперь должен быть определен как мусор, по крайней мере, в двух отдельных циклах сборки мусора, чтобы его можно было собрать. Когда первый цикл определяет, что это мусор, он становится пригодным для завершения. Из-за (тонкой, но, к сожалению, реальной) возможности того, что объект был "воскрешен" во время финализации, сборщик мусора должен запустить снова, прежде чем объект может быть фактически удален. И поскольку завершение могло не произойти своевременно, произвольное количество циклов сборки мусора могло произойти, пока объект ожидал завершения. Это может означать серьезные задержки в фактической очистке мусорных объектов, и именно поэтому вы можете получить OutOfMemoryErrors, даже если большая часть кучи является мусором.
для получения более подробной информации см. эту страницу: http://weblogs.java.net/blog/2006/05/04/understanding-weak-references
По сути, вы будете использовать Слабый реф, когда хотите связать некоторые дополнительные данные с объектами, исходный код которых не находится под вашим контролем. Используя слабую ссылку, вы свяжете жизненный цикл ваших мета-объектов с жизненным циклом первичных объектов.
Основным вариантом использования фантомных ссылок является реализация собственного потока финализатора без опасностей, связанных с механизмом по умолчанию, который вынужден сделать ссылку на предположительно недоступный объект доступной для кода финализации.
Мягкие ссылки в первую очередь предназначены для кеширования, но, как сказано в другом посте, они могут привести к катастрофическим последствиям на практике, подрывая саму суть кеширования. Основной GC (тот, который очистит ваши мягкие ссылки) обычно не происходит до тех пор, пока не возрастет нагрузка на производительность вашего приложения. Это время, когда вам больше всего нужен кеш, и время, когда вы, скорее всего, потеряете его - и все сразу.
Я думаю, что этот пост отвечает на ваш вопрос довольно хорошо.
В чем разница между мягкой ссылкой и слабой ссылкой в Java?
В основном, мягкая ссылка немного сильнее, чем слабая. Слабая ссылка будет отброшена в следующем цикле GC, в то время как мягкая ссылка останется в памяти до тех пор, пока не возникнет давление памяти, и JVM не захочет восстановить столько, сколько сможет.
Вы должны подумать о том, насколько важно для вашей программы, что имеющаяся у вас ссылка остается в силе. Для чего-то, что является чрезвычайно дешевым для воссоздания ссылки, я бы склонялся к WeakReference, но если это значение из БД, вы могли бы склониться к мягкой ссылке, так как вы не захотите перезапускать запрос, если в этом нет особой необходимости.
Объекты SoftReference не собираются, пока все объекты WeakReference не будут собраны сборщиком мусора.
Поэтому поместите менее важные объекты в объекты WeakReference и используйте объекты SoftReference для хранения более важных объектов.
Учитывая эти факты, вы должны использовать хорошие объекты Reference в зависимости от ваших потребностей в плане сборки мусора. Сначала собираются WeakReference, затем SoftReference и, наконец, PhantomReferences.
- Мягкие ссылки предназначены для реализации чувствительных к памяти кэшей
- Слабые ссылки предназначены для реализации канонизирующих отображений, которые не препятствуют восстановлению их ключей (или значений)
Между прочим, в некоторых случаях для целей кэширования может быть хорошей идеей использовать WeakReference вместо SoftReference, поскольку кэш может занимать много места в памяти, и поэтому его необходимо очистить.
Для PhantomReference использование отличается. O ни are for scheduling pre-mortem cleanup actions in a more flexible way than is possible with the Java finalization mechanism.
В этой статье расскажем немного о том, что может быть использование PhantomReference.