Ключ Guava "expireAfterWrite", похоже, не всегда работает

private Cache<Long, Response> responseCache = CacheBuilder.newBuilder()
            .maximumSize(10000)
            .expireAfterWrite(10, TimeUnit.MINUTES)
            .build();

Я ожидаю, что объекты ответа, которые не отправляются клиенту в течение 10 минут, истек и автоматически удалены из кеша, но я замечаю, что объекты Response не всегда истекают даже через 10, 15, 20 минут. Они истекают, когда кеш заполняется большими числами, но когда система переходит в режим ожидания, что-то вроде последних 500 объектов ответа, оно прекращает удаление этих объектов. Может кто-то помочь понять это поведение? Спасибо вам

Ответ 1

Это указано в документах:

Если expireAfterWrite или expireAfterAccess запрашиваются, записи могут быть удалены при каждой модификации кэша, при случайном доступе к кешу или при вызовах Cache.cleanUp(). Истекшие записи могут быть подсчитаны с помощью Cache.size(), но никогда не будут видны для операций чтения или записи.

И более подробная информация о вики:

Кэши, созданные с помощью CacheBuilder, не выполняют операции очистки и выселения "автоматически" или сразу после истечения значения или что-то в этом роде. Вместо этого он выполняет небольшие объемы обслуживания во время операций записи или во время периодических операций чтения, если записи встречаются редко.

Причиной этого является следующее: если мы хотим выполнить кеш нам нужно было бы создать поток, а его операции будут конкурировать с пользовательскими операциями для общих блокировок. Кроме того, некоторые среды ограничивают создание потоков, что делает CacheBuilder непригодным для использования в этой среде.

Вместо этого мы ставим выбор в свои руки. Если ваш кеш высокая пропускная способность, тогда вам не нужно беспокоиться о выполнении кеша техническое обслуживание для очистки истекших записей и т.п. Если ваш кеш делает записи редко, и вы не хотите, чтобы очистка блокировала кеш читает, вы можете создать свой собственный поток обслуживания, который вызывает Cache.cleanUp() через регулярные промежутки времени.

Если вы хотите запланировать регулярное обслуживание кеша для кеша, который только редко пишет, просто планируйте обслуживание, используя ScheduledExecutorService.