сборщика мусора и, следовательно, с его помощью можно влиять на автоматическое управление памятью • изучение Reference Objects API является шагом к пониманию работы сборщика мусора
оператора new • объекты занимают место в памяти и никогда не удаляются явно • память - ограниченный ресурс, который при таком подходе быстро закончится • следовательно, нужен способ нахождения и удаления неиспользуемых объектов для утилизации занимаемой ими памяти Зачем нужна сборка мусора?
его более продуктивным • программист не может случайно "уронить" JVM, некорректно освобождая память, что гарантирует целостность программы • однако, сборка мусора может повлиять на производительность программы, т.к. несет некоторые издержки: ◦ требуются дополнительные циклы процессора и ◦ память • программист почти не может контролировать этот процесс: ◦ когда будет запущен сборщик мусора? Достоинства и недостатки сборки мусора
обнаруживать объекты, ставшие мусором ◦ утилизировать занимаемую ими память • процесс обнаружения мусора обычно включает: ◦ определение корневого множества ссылок ◦ определение достижимости объектов из корневого множества • объекты, достижимые из корневого множества, считаются используемыми программой • недостижимые объекты считаются мусором Задачи сборщика мусора
методов ◦ статические переменные классов ◦ ссылки, зарегистрированные через JNI ◦ и другие • объекты, на которые ссылается корневое множество, считаются достижимыми • объекты, на которые ссылаются достижимые объекты, также считаются достижимыми (транзитивно)
до тех пор, пока до них существует хотя бы один путь из корневого множества • объекты на текущем уровне достижимости не могут быть утилизированы сборщиком мусора • когда исчезает последний путь до объекта, он переходит на уровень Finalizable Уровни достижимости объектов До версии Java 1.2 Reachable Finalizable Unreachable
на текущем уровне не достижимы из корневого множества • однако, могут вновь стать достижимыми после "воскрешения" в финализаторе • после выполнения сборщиком мусора финализаторов объекты переходят на уровень Unreachable Finalizable Unreachable
корневого множества, но и уже не могут стать достижимыми • недостижимые объекты могут быть утилизированы сборщиком мусора Уровни достижимости объектов До версии Java 1.2 Reachable Finalizable Unreachable
Reachable Weakly Reachable Finalizable Phantom Reachable Unreachable • существует путь из корневого множества до объекта не содержащий объектов-ссылок • объект остается сильно достижимым пока на него существует сильная ссылка из корневого множества или на него ссылается другой сильно достижимый объект • объект на текущем уровне достижимости не будет утилизирован сборщиком мусора
5 6 7 11 10 Корневое множество Недостижимые объекты 13 14 18 19 15 17 16 12 3 4 8 9 Сильная ссылка Сильно достижимый объект Объект-ссылка Слабо достижимый объект Недостижимый объект
Reachable Weakly Reachable Finalizable Phantom Reachable Unreachable • объект не является сильно достижимым • существует путь из корневого множества до объекта содержащий одну и более мягких ссылок • сборщик мусора может утилизировать такой объект при сборке, тогда он ◦ очищает все мягкие ссылки на объект ◦ добавляет ссылки в соответствующие очереди
Reachable Weakly Reachable Finalizable Phantom Reachable Unreachable • объект не является сильно и мягко достижимым • существует путь из корневого множества до объекта содержащий одну и более слабых ссылок • сборщик мусора должен утилизировать такой объект при сборке, тогда он ◦ очищает все слабые ссылки на объект ◦ добавляет ссылки в соответствующие очереди
Reachable Weakly Reachable Finalizable Phantom Reachable Unreachable • объект не является сильно, мягко и слабо достижимым • может быть "воскрешен" во время финализации
не был воскрешен во время финализации • существует путь из корневого множества до объекта содержащий одну или более фантомных ссылок • фантомные ссылки на объект ◦ будут добавлены в соответствующие очереди сборщиком мусора ◦ не будут автоматически очищены сборщиком мусора ◦ должны быть явно очищены в программе Уровни достижимости объектов С версии Java 1.2 Strongly Reachable Softly Reachable Weakly Reachable Finalizable Phantom Reachable Unreachable
• не был воскрешен во время финализации • может быть утилизирован сборщиком мусора Уровни достижимости объектов С версии Java 1.2 Strongly Reachable Softly Reachable Weakly Reachable Finalizable Phantom Reachable Unreachable
объект называемый референтом • референт задается при создании ссылки • также, при создании ссылка может быть ассоциирована с очередью Reference(T referent) Reference(T referent, ReferenceQueue<? super T> queue) T get() void clear() boolean isEnqueued()
помещаются в очередь сборщиком мусора в определенный момент их жизненного цикла • если ссылка появилась в очереди, значит уровень достижимости объекта изменился • приложение может: ◦ периодически опрашивать очередь с помощью poll() ◦ вызывать remove(), реализующий ожидание, если очередь пуста Reference<? extends T> poll() Reference<? extends T> remove(long timeout) Reference<? extends T> remove()
мусора при нехватке памяти ◦ сборщик мусора сам решает, когда наступает этот момент ◦ агрессивность очистки мягких ссылок можно настраивать с помощью ключа -XX:SoftRefLRUPolicyMSPerMB=1000 • гарантируется, что все мягкие ссылки будут очищены до того, как будет брошен java.lang.OutOfMemoryError • область применения: простое кэширование данных в памяти приложения SoftReference(T referent) SoftReference(T referent, ReferenceQueue<? super T> q)
мусора определил, что объект стал слабо достижимым • область применения: создание таблиц, в которых ключи не препятствуют удалению записей из таблицы сборщиком мусора ◦ см. java.util.WeakHashMap WeakReference(T referent) WeakReference(T referent, ReferenceQueue<? super T> q) Reference Objects API java.lang.ref.WeakReference
сильную ссылку на референта: ◦ вызов get() всегда возвращает null, даже если ссылка не очищена • фантомные ссылки должны очищаться явно в приложении, сборщик мусора этого не делает (или сами ссылки должны становиться недостижимыми) • область применения: ◦ оповещение приложения перед удалением объекта из памяти, чтобы произвести необходимую "уборку" ◦ замена финализаторам, не подверженная проблеме воскрешения объекта PhantomReference(T referent, ReferenceQueue<? super T> q) Reference Objects API java.lang.ref.PhantomReference