docs: @Override
    public void release(V value) {
      Preconditions.checkNotNull(value);
  
      final int bucketedSize = getBucketedSizeForValue(value);
      final int sizeInBytes = getSizeInBytes(bucketedSize);
      synchronized (this) {
        final Bucket<V> bucket = getBucketIfPresent(bucketedSize);
        if (!mInUseValues.remove(value)) {
          // This value was not 'known' to the pool (i.e.) allocated via the pool.
          // Something is going wrong, so let's free the value and report soft error.
          FLog.e(
              TAG,
              "release (free, value unrecognized) (object, size) = (%x, %s)",
              System.identityHashCode(value),
              bucketedSize);
          free(value);
          mPoolStatsTracker.onFree(sizeInBytes);
        } else {
          // free the value, if
          //  - pool exceeds maxSize
          //  - there is no bucket for this value
          //  - there is a bucket for this value, but it has exceeded its maxLength
          //  - the value is not reusable
          // If no bucket was found for the value, simply free it
          // We should free the value if no bucket is found, or if the bucket length cap is exceeded.
          // However, if the pool max size softcap is exceeded, it may not always be best to free
          // *this* value.
          if (bucket == null ||
              bucket.isMaxLengthExceeded() ||
              isMaxSizeSoftCapExceeded() ||
              !isReusable(value)) {
            if (bucket != null) {
              bucket.decrementInUseCount();
            }
  
            if (FLog.isLoggable(FLog.VERBOSE)) {
              FLog.v(
                  TAG,
                  "release (free) (object, size) = (%x, %s)",
                  System.identityHashCode(value),
                  bucketedSize);
            }
            free(value);
            mUsed.decrement(sizeInBytes);
            mPoolStatsTracker.onFree(sizeInBytes);
          } else {
            bucket.release(value);
            mFree.increment(sizeInBytes);
            mUsed.decrement(sizeInBytes);
            mPoolStatsTracker.onValueRelease(sizeInBytes);
            if (FLog.isLoggable(FLog.VERBOSE)) {
              FLog.v(
                  TAG,
                  "release (reuse) (object, size) = (%x, %s)",
                  System.identityHashCode(value),
                  bucketedSize);
            }
          }
        }
        logStats();
      }
    }