#java #garbage-collection #soft-references #g1gc
#java #сбор мусора #программные ссылки #g1gc
Вопрос:
Я хочу написать кеш с использованием SoftReference
s, используя как можно больше памяти, если это не станет слишком неэффективным.
Попытка оценить используемый размер путем вычисления размеров объектов или путем получения некоторого приближения используемой памяти JVM
к тупикам.
В javadoc даже указано, что SoftReference
s хороши для кэшей с поддержкой памяти, но нет жесткого правила о том, как JVM
реализация должна обрабатывать SoftReference
s. Я говорю только о реализации Oracle JVM
(версии 6.22 и выше и версии 7).
Теперь мои вопросы (пожалуйста, не стесняйтесь отвечать на частичные, групповые или любым другим удобным вам способом):
JVM
Учитывает ли последний доступ к объекту и удаляет только старые? Состояния Javadoc:Virtual machine implementations are, however, encouraged to bias against clearing recently-created or recently-used soft references.
- Что происходит, когда памяти становится мало?
JVM
Паникует и просто съедает все объекты? - Есть ли параметр, указывающий
JVM
, чтобы потреблять столько, сколько нужно, чтобы выжить (безOOME
ов) и жить здоровой жизнью (если процессор не запускает толькоGC
)
Ответ №1:
Я не думаю, что есть порядок. (Хотя я не уверен в порядке событий)
Но что происходит с мягкими ссылками, так это то, что всегда гарантируется, что они будут выпущены до того, как возникнет исключение нехватки памяти. Если у вас нет жесткой ссылки, указывающей на них.
Но вы должны знать, что вы можете попытаться получить к ним доступ, и они исчезнут. Я предполагаю, что сборщик мусора просто получит первую мягкую ссылку, которая соответствует количеству, необходимому для операции.
Ответ №2:
Хотя SoftReferences — классная функция, я лично не решаюсь использовать их в больших проектах, где я не знаю требований к памяти для любого другого компонента. Будет ли кеш SoftReference, забивающий память, заставлять другие части работать плохо?
Я бы вместо использования SoftReferences я бы подумал об использовании EHCache. Это позволяет вам ограничить размер определенных кэшей с точки зрения количества записей или, что еще лучше, байтов, используемых в памяти (это новая функция в предстоящей версии 2.5). Конечно, можно настроить различные стратегии удаления, такие как LRU. С помощью EHCache можно многое настроить.
Если вы используете Spring, то версия 3.1 также предоставит вам несколько приятных аннотаций на уровне метода @Cachable; EHCache можно использовать в качестве реализации кэширования.
Ответ №3:
Что происходит, когда памяти становится мало? JVM паникует и просто съедает все объекты?
Я точно знаю, что с Oracle 1.6 JVM это не так. Мне известна ситуация, когда сервер, обрабатывающий параллельные запросы, использует ответ, содержащий фактические данные внутри программной ссылки. Я заметил, что, когда один поток сообщает о ситуации с нехваткой памяти, программные ссылки других потоков продолжают сохранять свое содержимое (объекты, на которые ссылаются).
Есть ли параметр, указывающий JVM потреблять столько, сколько нужно, чтобы выжить (без OOME) и жить здоровой жизнью (если процессор не запускает только GC)
Чего достаточно, чтобы выжить? Вы имеете в виду, что если требуется X объем памяти, то восстанавливайте только программные ссылки, пока X не будет доступно? Я не нашел ни одного такого параметра настройки, но, как я уже сказал, JVM, похоже, не восстанавливает все программные ссылки, когда им нужно их восстановить.