code: public synchronized void scavenge() throws InterruptedException {
          int delta = this.totalCount - config.getMinSize();
          if (delta <= 0) return;
          int removed = 0;
          long now = System.currentTimeMillis();
          Poolable<T> obj;
          while (delta-- > 0 && (obj = objectQueue.poll()) != null) {
              // performance trade off: delta always decrease even if the queue is empty,
              // so it could take several intervals to shrink the pool to the configured min value.
              if (Log.isDebug())
                  Log.debug("obj=", obj, ", now-last=", now - obj.getLastAccessTs(), ", max idle=",
                      config.getMaxIdleMilliseconds());
              if (now - obj.getLastAccessTs() > config.getMaxIdleMilliseconds() &&
                      ThreadLocalRandom.current().nextDouble(1) < config.getScavengeRatio()) {
                  decreaseObject(obj); // shrink the pool size if the object reaches max idle time
                  removed++;
              } else {
                  objectQueue.put(obj); //put it back
              }
          }
          if (removed > 0) Log.debug(removed, " objects were scavenged.");
      }
docs: set the scavenge interval carefully