Java SoftReference, изменение поведения GC и GC

#java #garbage-collection #soft-references #g1gc

#java #сбор мусора #программные ссылки #g1gc

Вопрос:

Я хочу написать кеш с использованием SoftReference s, используя как можно больше памяти, если это не станет слишком неэффективным.

Попытка оценить используемый размер путем вычисления размеров объектов или путем получения некоторого приближения используемой памяти JVM к тупикам.

В javadoc даже указано, что SoftReference s хороши для кэшей с поддержкой памяти, но нет жесткого правила о том, как JVM реализация должна обрабатывать SoftReference s. Я говорю только о реализации Oracle JVM (версии 6.22 и выше и версии 7).

Теперь мои вопросы (пожалуйста, не стесняйтесь отвечать на частичные, групповые или любым другим удобным вам способом):

  1. JVM Учитывает ли последний доступ к объекту и удаляет только старые? Состояния Javadoc: Virtual machine implementations are, however, encouraged to bias against clearing recently-created or recently-used soft references.
  2. Что происходит, когда памяти становится мало? JVM Паникует и просто съедает все объекты?
  3. Есть ли параметр, указывающий 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, похоже, не восстанавливает все программные ссылки, когда им нужно их восстановить.