Реферат: Java: Управление ресурсами
В результате - список будет пухнуть, пухнуть, программа работает всё медленней и медленней, и, в конце концов, вылетает OutOfMemoryError.
Отследить такой сценарий можно при помощи специальных программ - профайлеров. Самые известные на данный момент - JProbe и OptimizeIt.
Бороться с этими вещами довольно просто - надо не забыть разрегистрироваться. Если Вы уверены, что объект-слушатель удаляется вместе с объектом - источником событий (например, когда они оба сидят внутри диалога), то этого делать не нужно - GC сам с ними разберётся.
Кэширование объектов.
Кэширование объектов применяется для повышения производительности. Когда объект меняется редко (или вообще не меняется в процессе работы программы), то часто полезно прочитать его один раз, и запомнить на него ссылку. Но ссылка - это противоречие между алгоритмом работы GC, а значит, этот объект никогда не будет собран GC (даже если он больше не нужен). Иногда это большого значения не имеет (памяти много, или все объекты требуются очень часто), но чаще желательно всё-таки иметь возможность почистить неиспользуемые объекты.
В JDK 1.2 для этих целей были добавлены несколько классов, самые интересные из них - WeakReference и SoftReference. Weak ("слабая") ссылка будет очищена, если на объект нет более "сильных" ссылок и объект попался под руку GC. Soft ("мягкая") ссылка будет очищена, если на объект нет обычных ссылок, и, к объекту не доступались по этой ссылке определённое время (эвристически рассчитываемое в зависимости от текущего окружения). Для кэширования лучше всего подходят ссылки типа Soft, т.к. в них учитывается частота обращения к объекту.
Непосредственно пользоваться этими ссылками не очень удобно, лучше написать контейнер с их использованием. Вот, например реализация класса SoftHashtable:
import java.lang.ref.SoftReference;
import java.util.Hashtable;
public class SoftHashtable extends Hashtable
{
public SoftHashtable() {}
public Object put(Object key,Object obj)
{
SoftReference ref = (SoftReference)super.put(key,new SoftReference(obj));
if( ref==null ) return null;
return ref.get();
}
public Object get(Object key)
{
SoftReference ref = (SoftReference)super.get(key);
if( ref==null ) return null;
return ref.get();
}
public Object remove(Object key)
{
SoftReference ref = (SoftReference)super.remove(key);
if( ref==null ) return null;
return ref.get();
}