#apache-commons-pool
Вопрос:
Мы используем GenericObjectPool из org.apache.commons.pool2.
Объекты, хранящиеся в пуле, довольно тяжелые — они потребляют много памяти и требуют много времени для создания.
Обычно требуется и берется только один объект из пула, но иногда нам нужны два объекта одновременно.
Мы используем следующую конфигурацию:
MaxIdle = 2;
MinIdle = 1;
И мы предварительно заполняем пул одним объектом во время создания пула, поэтому у нас всегда есть один объект, готовый к использованию. Кроме того, мы хотим, чтобы один объект все время находился в пуле, поэтому minIdle = 1.
В то же время, после того как мы взяли два объекта одновременно, мы хотим, чтобы второй объект был в конечном итоге уничтожен.
Мы используем политику DefaultEvictionPolicy со следующей конфигурацией:
MinEvictableIdleTime = -1; // not used
SoftMinEvictableIdleTime = a few minutes;
TimeBetweenEvictionRuns = a few minutes;
Проблема в том, что:
Когда первый объект берется из пула, он берется довольно долго (несколько минут). В пуле нет запросов на другой объект.
Но внезапно создается новый (второй) объект, и он переходит в режим ожидания.
Таким образом, у нас есть ненужный второй объект, который потребляет много процессора при его создании и много памяти. И это в то же время, когда обрабатывается первый объект, и процессор/память очень важны.
Этот второй объект выселяется позже, но он нам совсем не нужен.
Вопрос: как мы можем предотвратить создание этого второго ненужного и бездействующего объекта?
Как я понимаю, он создается потому, что у нас есть minIdle = 1, и когда первый объект берется из пула, не остается незанятых объектов. Возможно, он создан в том же потоке, который выполняет задание по выселению, я не знаю.
Что мы можем сделать?
Опять же: нам нужно, чтобы один объект присутствовал всегда (активный или бездействующий), а второй объект создавался только в том случае, если есть запрос на второй объект, когда первый активен (взят из пула). Мы не хотим, чтобы второй простаивающий объект создавался без явного запроса на него.